持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情
第三方框架整合Spring之FactoryBean(三)
前言
之前的文章中讲过第三方框架利用FactoryBean与Spring整合的过程及相关代码, 并利用FactoryBean写了一个关于RedisTemplate的小工具,
下面再来利用FactoryBean来实现一个关于Swagger配置的实用的小工具, 具体思路参考之前的文章, 这里不再赘述
实现的功能是通过yaml配置实现Swagger分组功能, 先看一下没整合FactoryBean之前Swagger如何实现根据不同的包生成不同的分组的
代码
swagger-ui相关maven
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.6</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0</version>
</dependency>
FactoryBean相关SwaggerGroupFactoryBean代码
SwaggerGroupFactoryBean
SwaggerGroups
BeanDefinitionRegistryPostProcessor相关SwaggerGroupBeanDefinitionRegistry代码
public class SwaggerGroupBeanDefinitionRegistry implements BeanDefinitionRegistryPostProcessor, EnvironmentAware {
private Environment environment;
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// 读取yaml中以multi-swagger-group开头的配置并绑定到SwaggerGroups
Binder.get(environment).bind("multi-swagger-group", SwaggerGroups.class).ifBound(s ->
s.getGroups().values().forEach(e -> {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(Docket.class);
GenericBeanDefinition definition = (GenericBeanDefinition) builder.getRawBeanDefinition();
definition.getConstructorArgumentValues().addGenericArgumentValue(e);
definition.setBeanClass(SwaggerGroupFactoryBean.class);
definition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_NAME);
// 注意这里使用groupName作为bean的名称
registry.registerBeanDefinition(e.getGroupName(), definition);
}));
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
}
Swagger配置相关代码
application-swagger.yml
# 以此为前缀
multi-swagger-group:
groups:
system-swagger-group-bean:
# 分组名称, 同时也是spring bean的名称
# 前面的 a. b. c. 是排序用的, 如果对顺序不敏感可以省略
group-name: b.系统
# 分组扫描的包名
base-package: com.xm.web.controller.system
business-swagger-group-bean:
group-name: c.业务
base-package: com.xm.web.controller.business
配置类
@EnableKnife4j
@EnableSwagger2
@Configuration
@Import(BeanValidatorPluginsConfiguration.class)
@Profile({"dev", "test"})
public class Swagger {
/**
* 通过构造注入所有Docket的方式
* 触发FactoryBean的getObject方法
*
* @param dockets 所有Docket
*/
public Swagger(List<Docket> dockets) {
}
/**
* 默认的Docket
*
* @return Docket
*/
@Bean
public Docket docket() {
SwaggerGroups.SwaggerGroup swaggerGroup = new SwaggerGroups.SwaggerGroup();
swaggerGroup.setGroupName("a.全部");
return Swagger.build(swaggerGroup);
}
public static Docket build(SwaggerGroups.SwaggerGroup swaggerGroup) {
List<Response> responses = Arrays.stream(ResConst.values())
.map(e -> new Response(String.valueOf(e.getCode()), e.getMessage(),
false, Collections.emptyList(), Collections.emptyList(),
Collections.emptyList(), Collections.emptyList()))
.collect(Collectors.toList());
HttpMethod[] httpMethods = HttpMethod.values();
Docket docket = new Docket(DocumentationType.SWAGGER_2);
for (HttpMethod httpMethod : httpMethods) {
// 添加全局响应码
docket.globalResponses(httpMethod, responses);
}
return docket
// 基础信息
.apiInfo(new ApiInfoBuilder()
.title(swaggerGroup.getTitle())
.description(swaggerGroup.getDescription())
.termsOfServiceUrl(swaggerGroup.getUrl())
.version(swaggerGroup.getVersion())
.build())
.select()
// 默认根据扫描Api注解, 如果配置了包名, 就扫描包
.apis(Objects.isNull(swaggerGroup.getBasePackage()) ?
RequestHandlerSelectors.withClassAnnotation(Api.class) :
RequestHandlerSelectors.basePackage(swaggerGroup.getBasePackage()))
.paths(PathSelectors.any()).build()
.forCodeGeneration(true)
// 分组名称
.groupName(swaggerGroup.getGroupName());
}
}
效果
可以看到通过以上配置实现了通过yaml配置的方式灵活的控制Swagger分组