应用场景
一个服务下有多个Module,启动当前服务,每个Module生成一个Docket文档,方便分别查看每个Module下的接口
功能描述
(1)获取项目服务中的所有的请求URL (2)获取每个请求URL对应的Controller所在的包,保存包名称到Set集合中,并且排除spring框架和springfox框架的包 (3)如果每个Module下的所有Controller类,都定义在同一个包下,则Set集合中的一条数据对应一个Module (4)遍历Set集合,一条数据生成一个Swagger Docket Bean
代码实现
/**
* @author 千本樱
* @date 2018/11/29
* @description 动态注册Swagger Docket,Controller所在的包名即是Docket分组名称
*/
@Component
@EnableSwagger2
public class RegistryDocket implements ApplicationContextAware {
private ConfigurableApplicationContext configurableApplicationContext;
private static final String SPRING_FOX_PACKAGE = "springfox.documentation";
private static final String SPRING_PACKAGE = "org.springframework";
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.configurableApplicationContext = (ConfigurableApplicationContext) applicationContext;
}
private ApiInfo apiInfo(String groupName){
return new ApiInfoBuilder()
.title(groupName + "模块Api文档")
.description("简单优雅的restfun风格,http://localhost:8080")
.termsOfServiceUrl("http://localhost:8080")
.version("1.0")
.build();
}
/**
* 根据请求地址所在的包名,动态注册多个Docket
* @return
*/
@Bean
public String createDocket(){
Set<String> packageList = packageList();
if (!CollectionUtils.isEmpty(packageList)){
packageList.forEach(packages -> {
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(Docket.class);
beanDefinitionBuilder.addConstructorArgValue(DocumentationType.SWAGGER_2);
BeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();
BeanDefinitionRegistry beanFactory = (BeanDefinitionRegistry) configurableApplicationContext.getBeanFactory();
beanFactory.registerBeanDefinition(packages, beanDefinition);
Docket docket = configurableApplicationContext.getBean(packages, Docket.class);
docket.groupName(packages)
.apiInfo(apiInfo(packages))
.select()
.apis(RequestHandlerSelectors.basePackage(packages))
.paths(PathSelectors.any())
.build();
});
}
return "createDocket";
}
/**
* 获取包名列表,排除Spring框架和springfox框架的包
* @return
*/
private Set<String> packageList(){
Set<String> packageSet = new HashSet<>();
Map<String, HandlerMapping> handlerMappingMap = BeanFactoryUtils.beansOfTypeIncludingAncestors(configurableApplicationContext, HandlerMapping.class);
for (HandlerMapping handlerMapping : handlerMappingMap.values()){
if (handlerMapping instanceof RequestMappingHandlerMapping){
RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping) handlerMapping;
Map<RequestMappingInfo, HandlerMethod> handlerMethods = requestMappingHandlerMapping.getHandlerMethods();
for (Map.Entry<RequestMappingInfo, HandlerMethod> requestMappingInfoHandlerMethodEntry : handlerMethods.entrySet()){
HandlerMethod mappingInfoValue = requestMappingInfoHandlerMethodEntry.getValue();
String packageName = mappingInfoValue.getBeanType().getPackage().getName();
if (!packageName.contains(SPRING_FOX_PACKAGE) && !packageName.contains(SPRING_PACKAGE)){
packageSet.add(packageName);
}
}
}
}
return packageSet;
}
}




