swagger是一个API框架,号称世界上最流行的API工具。它提供了API管理的全套解决方案,比如API在线编辑器,API UI展示界面,代码生成器等诸多功能。

如果想引入swagger进行API管理。目前 springfox 是一个很好的选择,它内部会自动解析Spring容器中Controller暴露出的接口,并且也提供了一个界面用于展示或调用这些API。下图就是简单的一个使用springfox的API展示界面。

springfox的前身是swagger-springmvc,用于springmvc与swagger的整合。

如若在springboot项目中使用springfox,需要3个步骤:

1、maven添加springfox依赖

2、启动类加上@EnableSwagger2注解

3、构造Docket bean用于展示API

配置完之后进入 http://{path}:{port}/swagger-ui.html 即可查看controller中的接口信息,并按照Docket中配置的规则进行展示。

springfox实现原理

在分析springfox实现原理之前,首先看下springfox对文档Documentation的定义:

文档Documentation定义得很清晰,主要由groupName(分组名)、basePath(contextPath)、apiListings(API列表集)、resourceListing(资源列表集)等属性组成。

其中API列表被封装成ApiListing。ApiListing中又持有ApiDesciption集合引用,每个ApiDesciption都持有一个API集合的引用,Operation也就是具体的接口操作,内部包含了该接口对应的http方法、produces、consumes、协议、参数集、响应消息集等诸多元素。

springfox通过spring-plugin的方式将Plugin注册到Spring上下文中,然后使用这些plugin进行API的扫描工作,这里的扫描工作其实也就是构造Documentation的工作,把扫描出的结果封装成Documentation并放入到DocumentationCache内存缓存中,之后swagger-ui界面展示的API信息通过Swagger2Controller暴露,Swagger2Controller内部直接从DocumentationCache中寻找Documentation。

下图就是部分Plugin具体构造对应的文档信息:

代码细节方面的分析:

很明显,入口处在@EnableSwagger2注解上,该注解会import一个配置类Swagger2DocumentationConfiguration。

Swagger2DocumentationConfiguration做的事情:

1、构造Bean。比如HandlerMapping,HandlerMapping是springmvc中用于处理请求与handler(controller中的方法)之间映射关系的接口,springboot中默认使用的HandlerMapping是RequestMappingHandlerMapping,Swagger2DocumentationConfiguration配置类里构造的是PropertySourcedRequestMappingHandlerMapping,该类继承RequestMappingHandlerMapping。

2、import其它配置类,比如SpringfoxWebMvcConfiguration、SwaggerCommonConfiguration

3、扫描指定包下的类,并注册到Spring上下文中

SpringfoxWebMvcConfiguration配置类做的事情跟Swagger2DocumentationConfiguration类似,不过多了一步构造PluginRegistry过程。该过程使用@EnablePluginRegistries注解实现:

@EnablePluginRegistries注解是spring-plugin模块提供的一个基于Plugin类型注册PluginRegistry实例到Spring上下文的注解。

@EnablePluginRegistries注解内部使用PluginRegistriesBeanDefinitionRegistrar注册器去获取注解的value属性(类型为Plugin接口的Class数组);然后遍历这个Plugin数组,针对每个Plugin在Spring上下文中注册PluginRegistryFactoryBean,并设置相应的name和属性。

如果处理的Plugin有@Qualifier注解,那么这个要注册的PluginRegistryFactoryBean的name就是@Qualifier注解的value,否则name就是插件名首字母小写+Registry的格式(比如DocumentationPlugin对应构造的bean的name就是documentationPluginRegistry)。

PluginRegistriesBeanDefinitionRegistrar注册器处理过程:

PluginRegistryFactoryBean是一个FactoryBean,其内部真正构造的bean的类型是OrderAwarePluginRegistry。OrderAwarePluginRegistry实例化过程中会调用create静态方法,传入的plugin集合使用aop代理生成一个ArrayList,这个list中的元素就是Spring上下文中所有的类型为之前遍历的Plugin的bean。

PluginRegistryFactoryBean的getObject方法:

这里的targetSource是在PluginRegistryFactoryBean的父类AbstractTypeAwareSupport(实现了InitializingBean接口)中的afterPropertiesSet方法中初始化的(type属性在PluginRegistriesBeanDefinitionRegistrar注册器中已经设置为遍历的Plugin):

BeansOfTypeTargetSource的getTarget方法:

举个例子:比如SpringfoxWebMvcConfiguration中的@EnablePluginRegistries注解里的DocumentationPlugin这个Plugin,在处理过程中会找出Spring上下文中所有的Docket(Docket实现了DocumentationPlugin接口),并把该集合设置成name为documentationPluginRegistry、类型为OrderAwarePluginRegistry的bean,注册到Spring上下文中。

DocumentationPluginsManager类会在之前提到过的配置类中被扫描出来,它内部的各个pluginRegistry属性都是@EnablePluginRegistries注解内部构造的各种pluginRegistry实例:

DocumentationPluginsBootstrapper启动类也会在之前提供的配置类中被扫描出来。它实现了SmartLifecycle接口,在start方法中,会获取之前初始化的所有documentationPlugins(也就是Spring上下文中的所有Docket)。遍历这些Docket并进行scan扫描(使用RequestMappingHandlerMapping的getHandlerMethods方法获取url与方法的所有映射关系,然后进行一系列API解析操作),扫描出来的结果封装成Documentation并添加到DocumentationCache中:

以上就是API解析、扫描的大致处理过程,整理如下:

下面分析一下HandlerMapping的处理过程。

PropertySourcedRequestMappingHandlerMapping在Swagger2DocumentationConfiguration配置类中被构造:

PropertySourcedRequestMappingHandlerMapping初始化过程中会设置优先级为Ordered.HIGHEST_PRECEDENCE + 1000,同时还会根据Swagger2Controller得到RequestMappingInfo映射信息,并设置到handlerMethods属性中。

PropertySourcedRequestMappingHandlerMapping复写了lookupHandlerMethod方法,首先会去handlerMethods属性中查询是否存在对应的映射关系,没找到的话使用下一个HandlerMapping进行处理:

Swagger2Controller中只有一个mapping方法,默认的path值为/v2/api-docs,可以通过配置 springfox.documentation.swagger.v2.path 进行修改。所以默认情况下 /v2/api-docs?group=person-api、/v2/api-docs?group=user-api 这些地址都会被Swagger2Controller所处理。

Swagger2Controller内部获取文档信息会去DocumentationCache中查找:

引入springfox带来的影响

影响主要有2点:

应用启动速度变慢,因为额外加载了springfox中的信息,同时内存中也缓存了这些API信息

多了一个HandlerMapping,并且优先级高。以下是springboot应用DispatcherServlet的HandlerMapping集合。其中springfox构造的PropertySourcedRequestMappingHandlerMapping优先级最高。优先级最高说明第一次查询映射关系都是走PropertySourcedRequestMappingHandlerMapping,而程序中大部分请求都是在RequestMappingHandlerMapping中处理的

优先级问题可以使用BeanPostProcessor处理,修改优先级:

本文作者:中间件小哥

阅读原文

本文为云栖社区原创内容,未经允许不得转载。

swagger内部类_API管理工具Swagger介绍及Springfox原理分析相关推荐

  1. API 管理工具 Swagger 和 RAP 的比较

    # 概述 微服务在当今的 web 开发中越来越盛行,前后端分离现在似乎也已成为中大型 Web 工程的基本模式,如何建立好前端调用和后端接口 (或者服务调用方和 API 提供方) 之间的契约,妥善处理好 ...

  2. ZooKeeper之Web管理工具Shepher介绍

    ZooKeeper之Web管理工具Shepher介绍 Shepher是ZooKeeper的管理工具.在小米,我们将它用作配置管理中心. 特征 ZooKeeper节点的可视化操作 ZooKeeper节点 ...

  3. ZooKeeper 的Web管理工具Shepher介绍

    ZooKeeper 的Web管理工具Shepher介绍 Shepher 是一款 ZooKeeper 的管理工具. 特性 ZooKeeper 节点的可视化操作 ZooKeeper 节点的快照管理 Zoo ...

  4. Mellanox网卡驱动升级固件管理工具使用介绍

    文章目录 1. Mellanox固件升级及管理工具使用介绍 介绍 1. MFT工具安装 2. 固件下载 3. 固件烧录 2. Mellanox驱动升级介绍 1. 解压文件 2. 安装依赖 3. 升级驱 ...

  5. API管理工具-Swagger

    1. Swagger的概念     Swagger是一款目前世界最流行的API管理工具.目前Swagger已经形成一个生态圈,能够管理API的整个生命周期,从设计.文档到测试与部署. 尤其擅长管理基于 ...

  6. 开源机器学习模型管理工具DVC介绍

    算法工程师往往在使用算法的过程中要不断地调整参数去找到最好的效果,俗称"调参民工".在不断的调参过程中,会产生各种各样的模型,如何记录好这些参数与模型效果对应的关系,往往另算法工程 ...

  7. MacOS 磁盘管理工具 diskutil 介绍

    https://www.jianshu.com/p/6a1f365617ad 电脑上的操作系统.应用程序和应用数据一般都需要保存在永久存储器中(通常就是硬盘),这样电脑断电后应用数据等就不会丢失. 为 ...

  8. 【包管理工具】Windows下的软件包管理工具Chocolatey介绍、安装软件出现错误的解决方法

    文章目录 1. Chocolatey是什么? 2. 为什么要使用Chocolatey? 3. 如何下载Chocolatey? 4. 如何使用Chocolatey? 5. 示例一:使用Chocolate ...

  9. 虚拟化之Proxmox VE集群管理工具pvecm介绍和使用

    一.pvecm简介   Proxmox VE 集群管理工具 pvecm 用于创建一个由多个物理服务器节点构成的"组".这样的一组服务器称为一个"集群".Prox ...

最新文章

  1. DL之CNN:卷积神经网络算法简介之原理简介(步幅/填充/特征图)、七大层级结构(动态图详解卷积/池化+方块法理解卷积运算)、CNN各层作用及其可视化等之详细攻略
  2. mfc控件变量没定义_WinCC字符串归档变量查询
  3. 【图网络】如何用Python实现算法:规划图技术(GraphPlanner)
  4. java服务熔断_springcloud-Hystrix-服务降级、服务熔断、服务限流
  5. Setup Factory打包时实现第三方DLL文件的注册
  6. 前端学习(1416):ajax的运行原理
  7. 同事说rar压缩有风险,让我用zip压缩文件
  8. 阿里云HBase发布冷存储特性,助你不改代码,1/3成本轻松搞定冷数据处理
  9. 运行Jenkins部署任务
  10. 【资源】史上最全数据集汇总
  11. python在哪里写代码-在哪里编写python代码
  12. mybatis运行原理详解
  13. 软件构架 课堂练习一
  14. RSA非对称加密算法介绍及其简单数学原理
  15. 机器学习算法一之基于K均值聚类算法实现数据聚类及二维图像像素分割
  16. 第三篇 ME909s-821设备描述符分析
  17. 【历史上的今天】12 月 20 日:苹果收购 NeXT;苏联超级计算机先驱诞生;《绝地求生》发布
  18. 鸿蒙当中使用WebView报空指针的问题
  19. 你可能已经被运营商http劫持了
  20. Java二分法查找数组中某个数的下标

热门文章

  1. mnist数据集图片提取出来
  2. vivox7刷linux系统,Vivo 找来宋仲基帮你送 X7
  3. json php 数组读写_PHP如何将数据写入JSON?
  4. 求1+2+3+...+n
  5. Matlab各种拟合
  6. MATLAB矩阵复制数据
  7. windows 开启mysql日志记录_windows下mysql日志开启与查询
  8. AUTOSAR从入门到精通100讲(二十)-特斯拉、高通、华为AI处理器深度分析
  9. 战略分析思路——商业模式及沙盘推演
  10. python创建一个包,如何从python包创建一个osx应用程序/ dmg?