先说一说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<DocumentationPlugin> 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<RequestHandler> 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 RelativePathProvider(servletContext))
.typeResolver(typeResolver)
.enableUrlTemplating(false)
.selector(ApiSelector.DEFAULT);
}
这里在给DocumentationContextBuilder
设置相关参数,