Swagger 自定义Model、Enum(SpringFox源码分析)

Springfox源码分析-自定义Model、Enum

先说一说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);
}

handlerProvidersRequestHandlerProvider 接口,实现类是 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。在看DefaultConfigurationcreate方法:

@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设置相关参数,至此拿到了 DocumentationContextBuilder

回到上面提到的buildContext方法,defaultContextBuilder方法执行完毕,接下来是 configure

return each.configure(this.defaultContextBuilder(each));

DocumentationPlugin只有一个实现类Docket,到这里就有点熟悉了。Docket对象是我们开发人员在外部通过@Bean来创建的,而外部赋值的对象值,最终都会整合到DocumentationContext。这里的config就是在二次赋值。可以看一下一般自己定义的Docket对象。

public class SwaggerConfig {
    ...
    @Bean
    public Docket docket() {
        ...
        return new Docket(Document
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值