文档
- 快速开始
- Knife4j 4.0 迭代计划
- 如何贡献代码
- 序章
- 社区
- 增强特性
- 3.1 增强模式
- 3.2 i18n 国际化
- 3.3 接口添加作者
- 3.4 自定义文档
- 3.5 访问权限控制
- 3.6 接口排序
- 3.7 分组排序
- 3.8 请求参数缓存
- 3.9 动态请求参数
- 3.10 导出离线文档
- 3.11 过滤请求参数
- 3.12 包含请求参数
- 3.13 搜索API接口
- 3.14 清除缓存
- 3.15 动态请求参数添加文档注释
- 3.16 动态响应参数添加文档注释
- 3.17 自定义Host
- 3.18 afterScript
- 3.19 OAuth2
- 3.20 导出 Postman
- 3.21 全局参数
- 3.22 自定义 Swagger Models 名称
- 3.23 自定义主页内容
- 3.24 自定义 Footer
- 3.25 JSR303
- 3.26 禁用调试
- 3.27 禁用搜索框
- 3.28 禁用 OpenApi 结构显示
- 3.29 版本控制
- 生态中间件
- 升级
中间件
- 中间件介绍
- Aggregation 微服务聚合中间件
- Desktop 独立渲染组件
OAS 简介
- OAS 简介
- OpenAPI 规范
- Java 注解
实战指南
- 示例代码
- Spring 单体架构
- Spring 微服务架构
- OAuth 2.0
- 微服务聚合实战
- ASP.NET Core
- Springfox 源码系列
- Springfox 源码系列
- springfox 源码分析(一) 程序入口
- springfox 源码分析(二) 初探 mapstruct
- springfox 源码分析(三) 初探 Spring Plugin 插件系统
- springfox 源码分析(四) 配置类初始化
- springfox 源码分析(五) Web 配置类 Plugin 插件的使用
- springfox 源码分析(六) Web 配置类扫描包作用探索
- springfox 源码分析(七) 文档初始化
- springfox 源码分析(八) 遍历接口获取 Model 对象
- springfox 源码分析(九) 文档初始化分组
- springfox 源码分析(十) 遍历接口获取 Model 对象
- springfox 源码分析(十一) 自定义添加 Swagger Models 功能实现
- springfox 源码分析(十二) 遍历接口获取 ApiDescription 集合
- springfox 源码分析(十三) 自定义扩展实现接口的排序
- springfox 源码分析(十四) 归档得到 ApiListing 接口集合
- springfox 源码分析(十五) 归档得到 Documentation 文档对象
- springfox 源码分析(十六) 分组接口 swagger-resouces
- springfox 源码分析(十七) Swagger2 接口文档示例接口 api-docs
- springfox 源码分析(十八) 自定义扩展实现分组的排序
- springfox 源码分析(十九) guava 库学习
- springfox 源码分析(二十一) 忽略参数 Class 类型
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
springfox 源码分析(九) 文档初始化分组
在前面我们了解了 DocumennationContext
的初始化过程,包括一系列的默认属性的赋值,接下来,开始真正的文档解析操作
我们的源码分析方式是按照springfox的文档初始化来进行归纳的,所以也是看到哪儿,就写到哪儿,当我们整个过程都研究完后,我会总结一篇文章来统一说明springfox的整个流程说明,或许以图文的方式来配合说明更能加深我们的印象.
我们在前面的初始化过程中,springfox将Spring环境中所有的接口都转换成了WebMvcRequestHandler,但是我们在外部创建Docket对象是对整个系统的接口文档来分组的,所以接下来需要对所有的接口进行分组(根据Docket对象传入的接口Selector来分).
先来看scan方法
/***
* 最终生成Documentation文档对象
* @param context
* @return
*/
public Documentation scan(DocumentationContext context) {
//得到分组接口
ApiListingReferenceScanResult result = apiListingReferenceScanner.scan(context);
//more...
}
通过 DocumentationContext
对象创建 ApiListingReferenceScanResult
对象
而 ApiListingReferenceScanResult
类只有一个属性,那就是根据controller分组后的接口方法
public class ApiListingReferenceScanResult {
//分组
private final Map<ResourceGroup, List<RequestMappingContext>> resourceGroupRequestMappings;
public ApiListingReferenceScanResult(Map<ResourceGroup, List<RequestMappingContext>> resourceGroupRequestMappings) {
this.resourceGroupRequestMappings = resourceGroupRequestMappings;
}
public Map<ResourceGroup, List<RequestMappingContext>> getResourceGroupRequestMappings() { return resourceGroupRequestMappings;
}
}
继续来看 apiListingReferenceScanner
对象的scan方法
public ApiListingReferenceScanResult scan(DocumentationContext context) {
LOG.info("Scanning for api listing references");
ArrayListMultimap<ResourceGroup, RequestMappingContext> resourceGroupRequestMappings
= ArrayListMultimap.create();
//拿到外部的接口选择器
//通常我们在创建Docket对象时,会赋予接口选择器,一般是以包路径来区分
ApiSelector selector = context.getApiSelector();
//过滤筛选
//如果是以package路径来区分的,则会根据接口的Handler的包路径是否已packagePath开始来进行匹配
//如果是以注解的方式,则会判断handler是否包含annotation注解
Iterable<RequestHandler> matchingHandlers = from(context.getRequestHandlers())
.filter(selector.getRequestHandlerSelector());
//
for (RequestHandler handler : matchingHandlers) {
//接口分组
//我们在一个Controller中会存在1个或多个接口方法
//所以resourceGroup和RequestMapping的关系是1:N
ResourceGroup resourceGroup = new ResourceGroup(
handler.groupName(),
handler.declaringClass(),
0);
//构建RequestMappingContext对象
RequestMappingContext requestMappingContext
= new RequestMappingContext(context, handler);
resourceGroupRequestMappings.put(resourceGroup, requestMappingContext);
}
return new ApiListingReferenceScanResult(asMap(resourceGroupRequestMappings));
}
从代码流程中,我们得知:
- 首先获取外部Docket对象的ApiSelector选择器,该选择器我们一般选择的是包路径
- 根据选择的规则进行接口过滤,此处会排除掉部分不符合规则的RequestHandler接口,通常是以package路径或者注解的方式,如果默认没有提供规则,那么springfox会根据在controller类上和方法上都没有标注
@ApiIgnore
注解的默认ApiSelctor来进行筛选 - 最后通过
ArrayListMultimap
来进行接口的归类操作 - 关于
ArrayListMultimap
的操作可参考springfox 源码分析(十九) guava库学习来了解
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论