优质文章,及时送达
巨人的肩膀:http://r6d.cn/SVuZ
开篇先说一说 Springfox 和 Swagger 的关系
- Swagger 是一种规范。
- springfox-swagger 是基于 Spring 生态系统的该规范的实现。
- springfox-swagger-ui 是对 swagger-ui 的封装,使得其可以使用 Spring 的服务。
由于工作中遇到需要基于 Swagger Json 做一些处理,但 Swagger Json 的格式不是那么满足需求。
❝本文 springfox-swagger 版本号:2.6.0
❞
本文从问题出发,探索涉及的源码。
1. GET 方法的参数对象
第一个问题,当方法是 GET 请求,但参数是一个自定义 Object,在展示时(生成的 JSON)是不包括本 Object 描述的。所以,就要看看什么时候会生成这些 Model 的描述。
万事有始有终,SpringFox 始就在:springfox.documentation.spring.web.plugins 下的 DocumentationPluginsBootstrapper。
该类实现了 SmartLifecycle 接口,实现此接口且通过 @Component 注入到容器的 bean, 容器初始化后会执行 start () 方法。
@Component
public class DocumentationPluginsBootstrapper implements SmartLifecycle {
···
}
接着看 start 方法
@Override
public void start() {
if (initialized.compareAndSet(false, true)) {
// 拿到 DocumentationPlugin 插件
List plugins = pluginOrdering()
.sortedCopy(documentationPluginsManager.documentationPlugins());for (DocumentationPlugin each : plugins) {
//获取文档类型
DocumentationType documentationType = each.getDocumentationType();if (each.isEnabled()) {
// 启用则扫描生成文档
scanDocumentation(buildContext(each));
}
}
}
}
调用了 buildContext 方法,通过 Docket 对象创建 DocumentaionContext 对象
private DocumentationContext buildContext(DocumentationPlugin each) {
return each.configure(this.defaultContextBuilder(each));
}
再往下走
private DocumentationContextBuilder defaultContextBuilder(DocumentationPlugin each) {
DocumentationType documentationType = each.getDocumentationType();
// 获取所有的RequestHnadler
List requestHandlers = FluentIterable.from(this.handlerProviders).transformAndConcat(this.handlers()).toList();return this.documentationPluginsManager.createContextBuilder(documentationType, this.defaultConfiguration).requestHandlers(requestHandlers);
}
handlerProviders 是 RequestHandlerProvider 接口,实现类是 WebMvcRequestHandlerProvider, 其中 requestHandlers 方法会接收 Spring 中的所有请求映射。
接着看 DocumentationContextBuilder 的构造过程:documentationPluginsManager.createContextBuilder
public DocumentationContextBuilder createContextBuilder(DocumentationType documentationType,
DefaultConfiguration defaultConfiguration) {
return defaultsProviders.getPluginFor(documentationType, defaultConfiguration)
.create(documentationType)
.withResourceGroupingStrategy(resourceGroupingStrategy(documentationType));
}
defaultsProviders 是也是一个插件接口 DefaultsProviderPlugin,只有一个实现类 DefaultConfiguration,不过该类未使用 @Compoent 注解,所以需要给一个替换值 defaultConfiguration,也就是 DefaultConfiguration。在看 DefaultConfiguration 的 create 方法:
@Override
public DocumentationContextBuilder create(DocumentationType documentationType) {
return new DocumentationContextBuilder(documentationType)
.operationOrdering(defaults.operationOrdering())
.apiDescriptionOrdering(defaults.apiDescriptionOrdering())
.apiListingReferenceOrdering(defaults.apiListingReferenceOrdering())
.additionalIgnorableTypes(defaults.defaultIgnorableParameterTypes())
.rules(defaults.defaultRules(typeResolver))
.defaultResponseMessages(defaults.defaultResponseMessages())
.pathProvider(new