別再糾結(jié) SpringFox!Spring Boot 3 親自推薦的文檔神器真香炸了
在 Spring Boot 項目中,接口文檔一直是開發(fā)者繞不開的話題。很多同學(xué)習(xí)慣使用 SpringFox,它曾經(jīng)是 Swagger 在 Spring 生態(tài)下的首選實現(xiàn),集成簡單,界面直觀。但自 2020 年起,SpringFox 停止了維護(hù),并且在 Spring Boot 3 中完全無法兼容,這讓不少團(tuán)隊在升級后面臨文檔組件“失效”的困境。
好消息是,Spring 官方社區(qū)已經(jīng)推薦了一個更現(xiàn)代的替代品——SpringDoc。它基于 OpenAPI 3 規(guī)范,天然支持 Spring Boot 3,全棧覆蓋 WebMvc、WebFlux、Spring Native 等場景。更重要的是,配置比 SpringFox 少得多,功能卻更全面,界面交互依舊由 Swagger-UI 提供。換句話說,它就是 Spring 世界里的“新一代文檔神器”。
本文將帶你深入了解 SpringDoc 的優(yōu)勢、配置方法、常見用法,并結(jié)合 Spring Security 演示如何在接口文檔中接入 JWT 認(rèn)證。
SpringDoc 簡介
SpringDoc 是一個專為 Spring Boot 設(shè)計的 API 文檔生成器,它基于 OpenAPI 3 標(biāo)準(zhǔn),可與 Spring WebMvc、Spring WebFlux 甚至 Native 模式無縫集成。
在 GitHub 上,SpringDoc 已經(jīng)獲得 3.5K+ Star,更新活躍、社區(qū)響應(yīng)快,逐漸成為 Spring Boot 官方推薦的 API 文檔方案。
架構(gòu)上,SpringDoc 并沒有脫離 Swagger 體系,而是作為 OpenAPI 3 在 Spring 生態(tài)中的實現(xiàn)層:
- 使用 Swagger-UI 渲染文檔界面;
- 生成 符合 OpenAPI 3 標(biāo)準(zhǔn)的 API 定義文件;
- 提供更友好的配置能力。
簡單來說,它既延續(xù)了 Swagger 的使用習(xí)慣,又讓開發(fā)者能夠更快擁抱新標(biāo)準(zhǔn)。
SpringDoc 與 Swagger 的關(guān)系
很多人容易混淆這三者:
- Swagger:最早的 API 規(guī)范標(biāo)準(zhǔn),后來演化為 OpenAPI。
- Swagger-UI:一個交互式 API 文檔展示工具,常見的“在線調(diào)試”功能就是它提供的。
- SpringDoc:Spring 世界里的 OpenAPI 3 適配實現(xiàn),底層仍依賴 Swagger-UI 做前端展示。
因此,可以把 SpringDoc 理解為 “Spring 生態(tài)里的 OpenAPI 3 解釋器”,它既與 Swagger 保持兼容,又解決了 Spring Boot 3 環(huán)境下的文檔適配問題。
SpringDoc 集成與配置
添加依賴
在 pom.xml
中加入以下依賴即可:
<!-- SpringDoc 依賴 -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>${springdoc-openapi.version}</version>
</dependency>
添加配置
在 src/main/resources/application.yml
中配置:
springdoc:
swagger-ui:
path: /swagger-ui.html # 修改 Swagger UI 路徑
enabled: true # 是否啟用 Swagger UI
api-docs:
path: /v3/api-docs # API 文檔 JSON 地址
enabled: true
group-configs:
- group: brand
paths-to-match: /brand/**
packages-to-scan: com.icoderoad.springdoc.controller
- group: admin
paths-to-match: /admin/**
packages-to-scan: com.icoderoad.springdoc.controller
default-flat-param-object: false
這樣就完成了基本的文檔配置。
SpringDoc 使用示例
配置文檔信息
在 src/main/java/com/icoderoad/config/SpringDocConfig.java
添加:
package com.icoderoad.config;
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author
* @description SpringDoc 基礎(chǔ)配置
*/
@Configuration
public class SpringDocConfig {
@Bean
public OpenAPI projectOpenAPI() {
return new OpenAPI()
.info(new Info().title("SpringDoc API")
.description("Spring Boot 3 集成 SpringDoc 的示例文檔")
.version("v1.0.0")
.license(new License().name("Apache 2.0")
.url("https://github.com/springdoc")))
.externalDocs(new ExternalDocumentation()
.description("更多學(xué)習(xí)資料")
.url("https://springdoc.org"));
}
}
編寫 Controller 示例
src/main/java/com/icoderoad/controller/PmsBrandController.java
:
package com.icoderoad.controller;
import com.icoderoad.domain.PmsBrand;
import com.icoderoad.service.PmsBrandService;
import com.icoderoad.common.CommonResult;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Tag(name = "PmsBrandController", description = "商品品牌管理")
@RestController
@RequestMapping("/brand")
public class PmsBrandController {
@Autowired
private PmsBrandService brandService;
@Operation(summary = "獲取所有品牌列表", description = "需要登錄后訪問")
@GetMapping("/listAll")
public CommonResult<List<PmsBrand>> listAll() {
return CommonResult.success(brandService.listAll());
}
@Operation(summary = "添加品牌")
@PostMapping("/create")
public CommonResult create(@RequestBody PmsBrand brand) {
int count = brandService.create(brand);
return count == 1 ? CommonResult.success(brand) : CommonResult.failed("操作失敗");
}
@Operation(summary = "更新指定 ID 的品牌信息")
@PostMapping("/update/{id}")
public CommonResult update(@PathVariable Long id, @RequestBody PmsBrand brand) {
int count = brandService.update(id, brand);
return count == 1 ? CommonResult.success(brand) : CommonResult.failed("操作失敗");
}
@Operation(summary = "刪除品牌")
@GetMapping("/delete/{id}")
public CommonResult delete(@PathVariable Long id) {
int count = brandService.delete(id);
return count == 1 ? CommonResult.success(null) : CommonResult.failed("操作失敗");
}
@Operation(summary = "分頁查詢品牌列表")
@GetMapping("/list")
public CommonResult<List<PmsBrand>> list(
@RequestParam(defaultValue = "1")
@Parameter(description = "頁碼") Integer pageNum,
@RequestParam(defaultValue = "3")
@Parameter(description = "每頁數(shù)量") Integer pageSize) {
return CommonResult.success(brandService.list(pageNum, pageSize));
}
@Operation(summary = "獲取品牌詳情")
@GetMapping("/{id}")
public CommonResult<PmsBrand> detail(@PathVariable Long id) {
return CommonResult.success(brandService.detail(id));
}
}
在實體類中使用注解
src/main/java/com/icoderoad/domain/PmsBrand.java
:
package com.icoderoad.domain;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class PmsBrand {
private Long id;
private String name;
@Schema(title = "首字母")
private String firstLetter;
private Integer sort;
@Schema(title = "是否為制造商:0->否;1->是")
private Integer factoryStatus;
private Integer showStatus;
@Schema(title = "產(chǎn)品數(shù)量")
private Integer productCount;
@Schema(title = "評論數(shù)量")
private Integer productCommentCount;
@Schema(title = "品牌 Logo")
private String logo;
@Schema(title = "專區(qū)大圖")
private String bigPic;
@Schema(title = "品牌故事")
private String brandStory;
}
結(jié)合 Spring Security 使用
在需要鑒權(quán)的場景下,可以在 OpenAPI
配置中加入 JWT 支持:
package com.icoderoad.config;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
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;
@Configuration
public class SpringDocSecurityConfig {
private static final String SECURITY_SCHEME_NAME = "Authorization";
@Bean
public OpenAPI secureOpenAPI() {
return new OpenAPI()
.info(new Info().title("SpringDoc 安全示例").version("v1.0.0"))
.addSecurityItem(new SecurityRequirement().addList(SECURITY_SCHEME_NAME))
.components(new Components()
.addSecuritySchemes(SECURITY_SCHEME_NAME,
new SecurityScheme()
.name(SECURITY_SCHEME_NAME)
.type(SecurityScheme.Type.HTTP)
.scheme("bearer")
.bearerFormat("JWT")));
}
}
這樣,就能在文檔頁面里輸入 JWT Token 進(jìn)行認(rèn)證調(diào)試。
運(yùn)行與測試
啟動項目后,訪問:
http://localhost:8088/swagger-ui.html
- 先調(diào)用登錄接口,獲取 JWT token;
- 點(diǎn)擊 Swagger-UI 頂部的認(rèn)證按鈕,輸入 token(無需手動加 Bearer 前綴);
- 之后就可以調(diào)試所有需要認(rèn)證的 API 接口了。
如果未傳遞 token,會返回鑒權(quán)失敗的提示。
總結(jié)
在 Spring Boot 3 時代,SpringFox 已經(jīng)不再適配,而 SpringDoc 則成為事實上的最佳替代方案:
- 輕量配置,幾乎開箱即用;
- 支持 WebMvc / WebFlux / Native 等多種場景;
- 結(jié)合 Spring Security,可以方便地調(diào)試 JWT 等安全方案;
- 社區(qū)維護(hù)活躍,版本更新頻繁。
如果你還在為 SpringFox 的兼容性問題頭疼,不妨試試 SpringDoc,它完全能成為新項目的首選文檔解決方案。
項目地址: https://github.com/springdoc/springdoc-openapi