JavaDoc、Swagger2 (SpringFox)、SpringDoc‑OpenAPI3 详解 & 区别
1. JavaDoc
本质:Java 原生注释工具,和框架无关
java
/**
* 发起签核流程
* @param oaSop sop提交vo
* @return 统一返回结果
*/
public AjaxResult startFlow(OaSopVO oaSop){}
- 作用:
- 写在类、方法、参数上的标准文档注释;
- IDE 可以悬浮看注释;
- 可以用
javadoc命令生成静态 html 文档; - Swagger2、SpringDoc 都可以读取 JavaDoc 注释,提取接口描述、参数说明。
- 特点:纯源码注释,不会自动扫描 HTTP 接口,本身不能生成在线接口网页。
- 缺点:不会识别 http 请求方式、请求体、路径、响应示例,只是文本注释。
2. Swagger2(SpringFox)
旧版本,基于 OpenAPI2 规范,SpringBoot2 时代主流,已经停止维护
- 依赖:
springfox‑swagger2 - 核心注解:
@Api、@ApiOperation、@ApiParam、@ApiModel、@ApiModelProperty - 作用:
- 扫描 Spring Controller,自动解析
@PostMapping/@GetMapping等; - 读取注解(也可以读取 JavaDoc),生成OpenAPI2 接口描述 json;
- 内置 swagger‑ui 网页,可以浏览器直接看接口、在线调试。
重大问题
- 停止维护,不支持 SpringBoot3、JDK17+;
- 很多版本兼容性 bug;
- 规范是 OpenAPI2,比较老旧。
java
@ApiOperation(value = "发起签核流程")
public AjaxResult startFlow(OaSopVO oaSop){}
3. SpringDoc‑OpenAPI3(现在主流)
实现 OpenAPI3 规范,替代 SpringFox Swagger2
- 依赖:
springdoc‑openapi‑starter - 核心注解:
@Operation、@Parameter、@Schema - 作用:
- 扫描 Controller,解析 Spring 注解;
- 支持读取 JavaDoc 注释(不用全部改成注解);
- 生成 OpenAPI3 标准 json;
- 内置 ui 页面,提供接口查看、在线调试;
- 原生支持 SpringBoot3、JDK17。
java
@Operation(summary = "发起签核流程")
public AjaxResult startFlow(OaSopVO oaSop){}
访问地址:
http://ip:port/v3/api-docs拿到 openapi3 原始 json;ui 页面默认/swagger‑ui/index.html
核心对比表格
表格
| 项目 | JavaDoc | Swagger2(SpringFox) | SpringDoc‑OpenAPI3 |
|---|---|---|---|
| 本质 | java 原生注释 | OpenAPI2 实现 | OpenAPI3 实现 |
| 是否框架 | 无,JDK 自带 | 第三方停止维护 | 第三方活跃维护 |
| 能否生成在线接口页面 | ❌不能,只能静态 html | ✅swagger‑ui | ✅swagger‑ui |
| 读取 javadoc | IDE、javadoc 工具 | ✅支持 | ✅支持 |
| 注解 | /** */ @param @return |
@Api @ApiOperation |
@Operation @Schema |
| SpringBoot3/JDK17 | 全部支持 | ❌不兼容 | ✅完美支持 |
| 规范 | 无 | OpenAPI 2.0(Swagger) | OpenAPI 3.x |
优先级规则(非常重要,开发踩坑高频)
- SpringDoc / Swagger 注解 > JavaDoc
如果写了
@Operation(summary="xxx"),方法上的 JavaDoc 第一行就会被覆盖,不再读取 javadoc 的描述。 只写 JavaDoc 不写注解:SpringDoc 自动解析 javadoc 作为 summary、description、param 说明。
- VO 字段
- Swagger2:
@ApiModelProperty(value = "SOP编号") - SpringDoc3:
@Schema(description = "SOP编号")
⚠️两者注解包名不一样,不能混用。
三种的协作关系
java
JavaDoc(源码写注释)
↓可被读取
Swagger2 / SpringDoc(框架扫描controller,生成openapi文档+ui页面)
- 老项目:Swagger2,可以继续用 JavaDoc;升级 Boot3 必须迁移 SpringDoc。
- 新项目:SpringDoc‑OpenAPI3;两种方案
- 偷懒:只写 JavaDoc,框架自动提取文档;
- 规范:写
@Operation + @Schema,可控性最强,不受注释格式影响。
面试背诵要点
- JavaDoc 是 JDK 原生注释,本身不能生成在线接口文档;Swagger2、SpringDoc 可以解析 JavaDoc。
- SpringFox (Swagger2) 已经停更,不支持 SpringBoot3;SpringDoc 是 OpenAPI3 的实现,作为替代。
- SpringDoc 既可以用专用注解,也可以复用原有 JavaDoc 注释。
- 注解优先级高于 JavaDoc,写了 @Operation 就不会读 javadoc 的方法描述。
Swagger2 (SpringFox) → SpringDoc OpenAPI3 注解迁移对照表
包名变化:
- Swagger2:
io.swagger.annotations.* - SpringDoc3:
io.swagger.v3.oas.annotations.*
Controller 类上
表格
| SpringFox Swagger2 | SpringDoc OpenAPI3 | 说明 |
|---|---|---|
@Api(tags = "SOP签核接口") |
@Tag(name = "SOP签核接口") |
控制器分组标签 |
接口方法上
表格
| SpringFox Swagger2 | SpringDoc OpenAPI3 | 说明 |
|---|---|---|
@ApiOperation(value="发起签核",notes="调用LuxLink外部签核") |
@Operation(summary="发起签核",description="调用LuxLink外部签核") |
接口摘要 + 详细描述 |
@ApiResponses({@ApiResponse(code=200,message="成功")}) |
@ApiResponses({@ApiResponse(responseCode="200",description="成功")}) |
响应码说明 |
方法参数
表格
| SpringFox Swagger2 | SpringDoc OpenAPI3 | 说明 |
|---|---|---|
@ApiParam(value = "SOP ID集合",required = true) |
@Parameter(description = "SOP ID集合",required = true) |
普通参数、query 参数 |
⚠️@RequestBody 请求体 VO 不要加 @Parameter,作用在实体类字段用
@Schema
VO/DTO 实体类(重点高频)
表格
| SpringFox Swagger2 | SpringDoc OpenAPI3 | 说明 |
|---|---|---|
@ApiModel(value="SOP提交VO",description="SOP提交入参") |
@Schema(description="SOP提交VO") |
实体类描述 |
@ApiModelProperty(value = "SOP编号",required = true,example="SOP‑20260819") |
@Schema(description = "SOP编号",requiredMode = Schema.RequiredMode.REQUIRED,example = "SOP‑20260819") |
实体字段说明 |
SpringDoc 没有
@ApiModelProperty,全部替换为@Schema
忽略接口 / 忽略字段
表格
| SpringFox Swagger2 | SpringDoc OpenAPI3 | 说明 |
|---|---|---|
@ApiIgnore |
@Hidden |
隐藏接口、隐藏字段不显示文档 |
鉴权配置
Swagger2
@ApiImplicitParams({
@ApiImplicitParam(name = "token",value="令牌",paramType="header")
})
SpringDoc OpenAPI3
方案 1:全局配置,推荐,不用每个接口写
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.components(new Components()
.addSecuritySchemes("token", new SecurityScheme()
.type(SecurityScheme.Type.APIKEY)
.in(SecurityScheme.In.HEADER)
.name("token")));
}
接口上加注解开启鉴权:
@Operation(summary = "发起签核")
@SecurityRequirement(name = "token")
迁移重要坑点
-
不再识别 @ApiModel / @ApiModelProperty ,导包一定要改成
io.swagger.v3.oas.annotations,导错包完全不生效。 -
@ApiModelProperty(required=true)迁移://旧
@ApiModelProperty(value="编号",required=true)
//新
@Schema(description="编号", requiredMode = Schema.RequiredMode.REQUIRED) -
SpringDoc 支持 JavaDoc ,老项目可以不完全替换注解,直接用 javadoc,减少改造工作量;一旦写
@Operation,javadoc 描述会被覆盖。 -
访问地址变更
- Swagger2:
/swagger-ui.html - SpringDoc:
/swagger-ui/index.html - openapi 原始 json:
/v3/api-docs
application.yml 常用配置
springdoc:
api-docs:
enabled: true
swagger-ui:
enabled: true
path: /swagger-ui/index.html
迁移步骤实操
- 删除 springfox 全部 maven 依赖
- 引入 springdoc‑openapi‑starter
- 删掉所有
@Api @ApiOperation @ApiModel @ApiModelProperty - 替换为
@Tag @Operation @Schema - 调整 swagger‑ui 访问路径
- 处理 token 鉴权全局配置
SpringDoc OpenAPI3 完整配置类(Token 鉴权,直接复制可用)
Maven 依赖(SpringBoot2 / SpringBoot3 通用)
<!-- springdoc openapi3 -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.6.0</version>
</dependency>
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* SpringDoc OpenAPI3 接口文档配置
*/
@Configuration
public class OpenApiConfig {
/**
* token请求头名称,和项目拦截器保持一致,若依项目一般是token
*/
private static final String TOKEN_HEADER = "token";
@Bean
public OpenAPI customOpenAPI() {
// 设置token全局安全方案
SecurityScheme securityScheme = new SecurityScheme()
.type(SecurityScheme.Type.APIKEY)
.in(SecurityScheme.In.HEADER)
.name(TOKEN_HEADER);
Components components = new Components()
.addSecuritySchemes(TOKEN_HEADER, securityScheme);
// 文档基本信息
Info info = new Info()
.title("后端接口文档")
.version("V1.0.0")
.description("系统API接口文档")
.contact(new Contact().name("开发组"))
.license(new License().name("Apache 2.0"));
return new OpenAPI()
.info(info)
.components(components)
// 全局生效token:所有接口调试框都会带上token输入框,不需要每个接口写@SecurityRequirement
.addSecurityItem(new SecurityRequirement().addList(TOKEN_HEADER));
}
}
生产环境配合 profile 的小补充
这个配置类全部生效,生产环境不希望暴露文档,可以用@Profile({"dev","test"}),只有开发、测试环境才生成这个 Bean:
@Configuration
@Profile({"dev","test"}) // 生产prod环境该配置类直接不生效
public class OpenApiConfig {
application.yml 配套配置
springdoc:
api-docs:
# 是否开启openapi json输出,生产环境可以关闭 false
enabled: true
path: /v3/api-docs
swagger-ui:
enabled: true
path: /swagger-ui/index.html
# 页面展开模式 none/list/full
doc-expansion: list
访问地址
- 文档页面:
http://127.0.0.1:端口/swagger-ui/index.html - OpenAPI 原始 json:
http://127.0.0.1:端口/v3/api-docs
关键点说明
-
addSecurityItem写在 OpenAPI 对象:全局生效 ,所有接口页面都会出现 token 输入框,不用每个 controller / 方法加@SecurityRequirement,适合若依这类统一 token 鉴权项目。 -
如果不写全局,需要接口上手动添加:
@Operation(summary = "发起签核流程")
@SecurityRequirement(name = "token")
public AjaxResult startFlow(){} -
生产环境关闭文档:修改
springdoc.api-docs.enabled=false、springdoc.swagger-ui.enabled=false
Controller 示例(结合注解 + javadoc)
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@RestController
@RequestMapping("/sop")
@Tag(name = "SOP签核接口")
public class SopController {
/**
* 调用LuxLink外部签核接口,发起签核流程
* @param oaSop sop提交vo
* @param list 生成的OA SOP id集合
* @return AjaxResult
*/
@Operation(summary = "调用LuxLink外部签核接口,发起签核流程", description = "对接外部LuxLink系统,提交SOP签核")
@PostMapping("/startFlow")
public AjaxResult startFlow(OaSopVO oaSop, @RequestBody List<Long> list) {
return AjaxResult.success();
}
}
VO 实体示例
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "SOP提交VO")
public class OaSopVO {
@Schema(description = "SOP编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "SOP‑20260819‑001")
private String sopNo;
@Schema(description = "版本号", example = "A0")
private String version;
}
常见坑
- 导包不要导入旧的
io.swagger.annotations,全部用io.swagger.v3.oas.annotations - SpringBoot3 必须使用
springdoc‑openapi‑starter‑webmvc‑ui,旧的springdoc‑openapi‑ui已废弃 - 配置类必须加
@Configuration,Spring 才会把 OpenAPI 注册为 Bean