自定义Knife4j-spring-boot-starter

在前后台开发时,需要将接口信息封装成接口文档,可选用knife4j框架生成API接口文档。

knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案,前身是swagger-bootstrap-ui,取名knife4j是希望它能像一把匕首一样小巧,轻量,并且功能强悍!其底层是对Springfox的封装,使用方式也和Springfox一致,只是对接口文档UI进行了优化。

为了避免重复开发,可将该功能抽离成一个通用的功能,可自定义一个Knife4j-spring-boot-starter,在实际运用时,引用该starter的坐标即可。
如何自定义一个starter,可参考我的上一篇文章Springboot Starter介绍以及实现自定义Starter

1 依赖导入


<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>


    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.2.2.RELEASEversion>
    parent>

    <groupId>com.startergroupId>
    <artifactId>swagger-spring-boot-starterartifactId>
    <version>1.0version>


    <dependencies>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starterartifactId>
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-autoconfigureartifactId>
        dependency>



        <dependency>
            <groupId>com.github.xiaoymingroupId>
            <artifactId>knife4j-spring-boot-starterartifactId>
            <version>2.0.1version>
        dependency>


        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
        dependency>
    dependencies>

project>

2 定义SwaggerProperties

/**
 * @author lyf
 * @projectName swagger-starter
 * @date 2022/5/27 上午 10:55
 * @description
 */

@Data
@ConfigurationProperties(prefix = "swagger2")
public class SwaggerProperties {


    /**
     * 是否开启swagger服务,默认是关闭swagger文档的服务
     */
    private boolean enabled = false;

    /**
     * 每个Docket对象的配置信息
     */
    Map<String, SwaggerInnerProperties> dockets = new HashMap<>();

}

@Data
class SwaggerInnerProperties {

    //api info properties;

    /**
     * api group
     */
    private String group;

    /**
     * api info  标题
     */
    private String title;

    /**
     * api info 描述
     */
    private String description;

    /**
     * api info 版本
     */
    private String version;

    //Contact联系人设置

    /**
     * api info 中的联系人信息
     */
    private ContactInfo ContactInfo=new ContactInfo();

    /**
     * api 有效的包路径
     */
    private String basePackage;

    /**
     * API 路径设置
     */
    private List<String> baseUrls = new ArrayList<>();

    /**
     * 被排除的路径
     */
    private List<String> excludePaths = new ArrayList<>();


    /**
     * 全局参数
     */
    private List<GlobaleParamsConfig>globaleParams=new ArrayList<>();

}

@Data
class ContactInfo {

    /**
     * 联系人名字
     */
    private String name;
    /**
     * 联系人url
     */
    private String url;
    /**
     * 联系人邮箱
     */
    private String email;
}


@Data
class GlobaleParamsConfig {

    /**
     * 全局参数
     */
    private String name;

    /**
     * 参数描述
     */
    private String description;
    /**
     * 参数类型
     */
    private String type;
    /**
     * 是否未必填的
     */
    private boolean required=false;
}

3 定义SwaggerAutoConfiguration

/**
 * @author lyf
 * @projectName swagger-starter
 * @date 2022/5/27 上午 10:56
 * @description EnableSwagger2 开启swagger2
 * 当且仅当swagger2.enabled=true时,加载List的Bean
 */
@EnableSwagger2
@Configuration
@EnableConfigurationProperties(SwaggerProperties.class)
@ConditionalOnProperty(name = "enabled",prefix = "swagger2",havingValue = "true")
public class SwaggerAutoConfiguration implements BeanFactoryAware {

    private Logger logger= LoggerFactory.getLogger(this.getClass());

    @Autowired
    private SwaggerProperties properties;
    /**
     * bean 工厂,遍历创建
     */
    private BeanFactory beanFactory;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory=beanFactory;
    }


    public SwaggerAutoConfiguration(SwaggerProperties properties) {
        this.properties = properties;
    }



    @Bean
    public List<Docket> createDockets(SwaggerProperties properties){
        ConfigurableBeanFactory configurableBeanFactory =
                (ConfigurableBeanFactory) beanFactory;
        List<Docket> docketList=new ArrayList<>();
        if(properties.getDockets()!=null&&properties.getDockets().size()>0){
            //遍历创建Docket文档
            if(properties.getDockets().isEmpty()){
                logger.error("docket配置信息错误");
            }else{
                //遍历创建Docket文档
                for(String group:properties.getDockets().keySet()){
                     SwaggerInnerProperties innerProperties=properties.dockets.get(group);
                     Docket docket=createOneDocket(innerProperties);
                     //bean工厂创建Bean
                     configurableBeanFactory.registerSingleton(group, docket);
                     docketList.add(docket);
                }
            }


        }
        return docketList;
    }


    /**
     * 创建一个Docket
     * @param innerProperties
     * @return
     */
    public Docket  createOneDocket(SwaggerInnerProperties innerProperties){
        Docket docket=new Docket(DocumentationType.SWAGGER_2);
        docket.groupName(innerProperties.getGroup());
        //配置Api Info
        docket.apiInfo(createApiInfo(innerProperties));
        //设置请求路径
        docket.select().apis(RequestHandlerSelectors.basePackage(innerProperties.getBasePackage()));

        // base-path处理
        // 当没有配置任何path的时候,解析/**
        if (innerProperties.getBaseUrls().isEmpty()) {
            innerProperties.getBaseUrls().add("/**");
        }
        List<Predicate<String>> basePath = new ArrayList<>();
        for (String path : innerProperties.getBaseUrls()) {
            basePath.add(PathSelectors.ant(path));
        }

        // exclude-path处理
        List<Predicate<String>> excludePath = new ArrayList<>();
        for (String path : innerProperties.getExcludePaths()) {
            excludePath.add(PathSelectors.ant(path));
        }

        docket.select().paths(Predicates.and(Predicates.not(Predicates.or(excludePath)),Predicates.or(basePath)));
        //配置全局参数
        if(innerProperties.getGlobaleParams().size()>0){
            List<Parameter>parameters=setParametes(innerProperties.getGlobaleParams());
            docket.globalOperationParameters(parameters);
        }


        return docket;
    }


    /**
     * 根据配置信息配置API INFO信息
     * @param innerProperties
     * @return
     */
    public ApiInfo createApiInfo(SwaggerInnerProperties innerProperties){
        ApiInfo apiInfo=new ApiInfoBuilder()
                .version(innerProperties.getVersion())
                .title(innerProperties.getTitle())
                .description(innerProperties.getDescription())
                .contact(new Contact(innerProperties.getContactInfo().getName(),innerProperties.getContactInfo().getUrl(),innerProperties.getContactInfo().getEmail()))
                .build();
        return apiInfo;
    }


    /**
     * 设置全局参数,默认添加到header中
     * @param globaleParams
     * @return
     */
    public List<Parameter>setParametes(List<GlobaleParamsConfig>globaleParams){
        List<Parameter>parameterList=new ArrayList<>();
        for(GlobaleParamsConfig config:globaleParams){
            ParameterBuilder parameterBuilder = new ParameterBuilder();
            // header query cookie形式的
            parameterBuilder.name(config.getName()).description(config.getDescription()).modelRef(new ModelRef(config.getType())).parameterType("header").required(config.isRequired());
            Parameter build = parameterBuilder.build();
            parameterList.add(build);
        }

        return parameterList;
    }
    
}

4 配置spring.factories

项目结构如下
自定义Knife4j-spring-boot-starter_第1张图片
在类路径下META-INF 新建spring.factories文件。

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.config.SwaggerAutoConfiguration

5 测试

新建项目,引入依赖

        <dependency>
            <groupId>com.starter</groupId>
            <artifactId>swagger-spring-boot-starter</artifactId>
            <version>1.0</version>
        </dependency>

配置

#SwaggerProperties
swagger2:
  enabled: true
  dockets:
     test:
       group: test
       title: test-title
       description: test-description
       version: version1
       ContactInfo:
         name: lyf
         url: lyf-url
         email: lyf-email
       basePackage: com.foxconn.assetmanagement.test
     tes1:
         group: test1
         title: test1-title
         description: test1-description
         version: version2
         ContactInfo:
           name: lyf
           url: lyf-url
           email: lyf-email
         basePackage: com.foxconn.assetmanagement.test1

项目路径如下
自定义Knife4j-spring-boot-starter_第2张图片
项目启动后输入localhost:8080/doc.html
自定义Knife4j-spring-boot-starter_第3张图片

你可能感兴趣的:(java学习笔记,spring,java,spring,boot)