第三方框架整合Spring之FactoryBean(三)

228 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情

第三方框架整合Spring之FactoryBean(三)

前言

之前的文章中讲过第三方框架利用FactoryBean与Spring整合的过程及相关代码, 并利用FactoryBean写了一个关于RedisTemplate的小工具, 下面再来利用FactoryBean来实现一个关于Swagger配置的实用的小工具, 具体思路参考之前的文章, 这里不再赘述

实现的功能是通过yaml配置实现Swagger分组功能, 先看一下没整合FactoryBean之前Swagger如何实现根据不同的包生成不同的分组的

微信图片_20220601112238.png

代码

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

微信图片_20220601112405.png

SwaggerGroups

微信图片_20220601112332.png

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分组

微信图片_20220601112128.png