SpringCloud Alibaba微服务番外一 - Swagger自定义自动配置

简介: SpringCloud Alibaba微服务番外一 - Swagger自定义自动配置

概述


我们的所有微服务若想集成Swagger在线接口文档,都需要在各自模块中建立一个Swagger的配置类,关键代码如下:

@Configuration
@EnableSwagger2
publicclass SwaggerConfig {
    privatestaticfinal String VERSION = "1.0.0";
    /**
     * 创建API
     */
    @Bean
    public Docket createRestApi(){
        returnnew Docket(DocumentationType.SWAGGER_2)
      .enable(true)
      .apiInfo(apiInfo())
      .select()
      .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
      .paths(PathSelectors.any())
      .build();
    }
    /**
     * 添加摘要信息
     */
    private ApiInfo apiInfo() {
        returnnew ApiInfoBuilder()
      .title("product-server接口文档")
      .contact(new Contact("JAVA日知录","http://javadaily.cn","jianzh5@163.com"))
      .description("product-server接口文档")
      .version(VERSION)
      .build();
    }
}

这样每个模块中都有一个SwaggerConfig配置类,他们的逻辑基本都一样,只是一些摘要信息不一样。这明显也算是违反了 DRY(Don't Repeat Yourself) 原则,这次我们来优化优化它,通过修改配置文件让Swagger自动配置。

不过在编写代码之前我们还是需要先了解一下SpringBoot的自动配置原理。


SpringBoot自动配置原理


SpringBoot项目启动类上都会添加@SpringBootApplication 注解,这个注解是个组合注解,他的核心功能是开启自动配置注解@EnableAutoConfiguration,如下图所示:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public@interface EnableAutoConfiguration {
   。。。
}

@EnableAutoConfiguration 又通过@Import 注解导入了AutoConfigurationImportSelector。通过对AutoConfigurationImportSelectorselectImports 方法的跟踪,我们找到SpringBoot启动时会通过SpringFactoriesLoader.loadFactoryNames 方法 从 META-INF/spring.factories 这个文件下去寻找有没有自动配置类。

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
  List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
  Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
  return configurations;
}


spring.factories

在项目中打开spring-boot-autoconfigure-2.1.9.RELEASE.jar,然后在META-INF文件夹下打开spring.factories,截取部分内容如下:

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

这个文件是一组的key=value的形式,通过value找到了自定义配置类,这里选取一个我们比较常见的配置类org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,打开源码:

@Configuration
@ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class})
@EnableConfigurationProperties({DataSourceProperties.class})
@Import({DataSourcePoolMetadataProvidersConfiguration.class, DataSourceInitializationConfiguration.class})
publicclass DataSourceAutoConfiguration {
  ...
}

这里我们又发现配置类上使用了@EnableConfigurationProperties({DataSourceProperties.class}),这个注解是去加载配置类。


application.properties

再打开DataSourceProperties.class,代码如下:

@ConfigurationProperties(
    prefix = "spring.datasource"
)
publicclass DataSourceProperties implements BeanClassLoaderAware, InitializingBean {
    private ClassLoader classLoader;
    private String name;
    privateboolean generateUniqueName;
    private Class<? extends DataSource> type;
    private String driverClassName;
    private String url;
    private String username;
    private String password;
  ...
}

看到这里大家都应该很熟悉了,主要是通过注解 @ConfigurationProperties 从配置文件中加载spring.datasource开头的配置,如我们经常用的数据库配置

spring:
  datasource:
    type:com.zaxxer.hikari.HikariDataSource
    url:jdbc:mysql://xxxxxxx/cloud_alibaba?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
    username:xxx
    password:xxxxxx
    driver-class-name:com.mysql.jdbc.Driver

从配置文件获取相关配置注入到DataSourceProperties这个类中


总结

通过观察源码我们找到了SpringBoot自定义配置类的加载过程,主要是从META-INF/spring.factories 找到对应的启动类,启动类上再通过配置类加载配置文件。说起来很简单,但是实现起来还是很复杂的。接下来我们就根据我们的理解来完成Swagger的自动配置。


自定义Swagger自动配置


这里可能有人会问,虽然看完了自定义配置的加载逻辑,但是还是不会写怎么办?

不会写没关系啊,咱们不是会复制粘贴吗?

我们以org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration为例,开始我们的自定义配置(Copy,Paste)过程


建立配置文件

我们在common模块建立resources/META-INF/spring.factories 文件,粘贴上面的配置进行修改

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    com.javadaily.autoconfigure.SwaggerAutoConfiguration


建立配置类,从配置文件读取配置

先想想我们需要哪些配置,一个title,一个description,还有一个enable用来控制是否开放在线测试,分析清楚了我们就建立对应的配置类SwaggerProperties

@Data
@ConfigurationProperties(prefix = "javadaily.swagger")
publicclass SwaggerProperties {
    /**
     * 是否启用swagger,生产环境建议关闭
     */
    privateboolean enabled;
    /**
     * 文档标题
     */
    private String title;
    /**
     * 文档描述
     */
    private String description;
}


建立自定义配置类

核心代码,但是实现起来比较简单。

拷贝原来的配置类内容,加上相关注解,注入配置类,将原来写死的地方改成从配置类获取即可。

@Slf4j
@Configuration
//注入配置类
@EnableConfigurationProperties({SwaggerProperties.class})
//根据配置文件决定是否自动配置
@ConditionalOnProperty(prefix = "javadaily.swagger", name = "enabled", havingValue = "true")
@Import({Swagger2DocumentationConfiguration.class})
publicclass SwaggerConfig {
    privatestaticfinal String VERSION = "1.0.0";
  private SwaggerProperties swaggerProperties;
    public SwaggerAutoConfiguration (SwaggerProperties swaggerProperties){
        this.swaggerProperties = swaggerProperties;
    }
    /**
     * 创建API
     */
    @Bean
    public Docket createRestApi(){
        returnnew Docket(DocumentationType.SWAGGER_2)
      .enable(true)
      .apiInfo(apiInfo())
      .select()
      .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
      .paths(PathSelectors.any())
      .build();
    }
    /**
     * 添加摘要信息
     */
    private ApiInfo apiInfo() {
        returnnew ApiInfoBuilder()
      .contact(new Contact("JAVA日知录","http://javadaily.cn","jianzh5@163.com"))
      .title(swaggerProperties.getTitle())
      .description(swaggerProperties.getDescription())
      .version(VERSION)
      .build();
    }
}


在微服务层的配置文件上加入swagger相关的配置

## swagger自定义配置属性
javadaily:
  swagger:
    enabled:true
    title:account-service在线接口平台
    description:account-service微服务相关接口

注意:这里配置文件需要以javadaily.swagger前缀开始,跟上面的配置类相对应

经过以上四步我们完成了Swagger的自定义自动配置,接下来就是在服务层引入common模块,然后删除掉SwaggerConfig类,让common模块给我们自动配置。

是不是很简单呢,你们也来试试吧!


好了,各位朋友们,本期的内容到此就全部结束啦,能看到这里的同学都是优秀的同学,下一个升职加薪的就是你了!

目录
相关文章
|
1月前
|
Dubbo Java 应用服务中间件
Spring Cloud Dubbo:微服务通信的高效解决方案
【10月更文挑战第15天】随着信息技术的发展,微服务架构成为企业应用开发的主流。Spring Cloud Dubbo结合了Dubbo的高性能RPC和Spring Cloud的生态系统,提供高效、稳定的微服务通信解决方案。它支持多种通信协议,具备服务注册与发现、负载均衡及容错机制,简化了服务调用的复杂性,使开发者能更专注于业务逻辑的实现。
58 2
|
1月前
|
Dubbo Java 应用服务中间件
Dubbo学习圣经:从入门到精通 Dubbo3.0 + SpringCloud Alibaba 微服务基础框架
尼恩团队的15大技术圣经,旨在帮助开发者系统化、体系化地掌握核心技术,提升技术实力,从而在面试和工作中脱颖而出。本文介绍了如何使用Dubbo3.0与Spring Cloud Gateway进行整合,解决传统Dubbo架构缺乏HTTP入口的问题,实现高性能的微服务网关。
|
1月前
|
JSON Java 数据格式
【微服务】SpringCloud之Feign远程调用
本文介绍了使用Feign作为HTTP客户端替代RestTemplate进行远程调用的优势及具体使用方法。Feign通过声明式接口简化了HTTP请求的发送,提高了代码的可读性和维护性。文章详细描述了Feign的搭建步骤,包括引入依赖、添加注解、编写FeignClient接口和调用代码,并提供了自定义配置的示例,如修改日志级别等。
89 1
|
1月前
|
人工智能 文字识别 Java
SpringCloud+Python 混合微服务,如何打造AI分布式业务应用的技术底层?
尼恩,一位拥有20年架构经验的老架构师,通过其深厚的架构功力,成功指导了一位9年经验的网易工程师转型为大模型架构师,薪资逆涨50%,年薪近80W。尼恩的指导不仅帮助这位工程师在一年内成为大模型架构师,还让他管理起了10人团队,产品成功应用于多家大中型企业。尼恩因此决定编写《LLM大模型学习圣经》系列,帮助更多人掌握大模型架构,实现职业跃迁。该系列包括《从0到1吃透Transformer技术底座》、《从0到1精通RAG架构》等,旨在系统化、体系化地讲解大模型技术,助力读者实现“offer直提”。此外,尼恩还分享了多个技术圣经,如《NIO圣经》、《Docker圣经》等,帮助读者深入理解核心技术。
SpringCloud+Python 混合微服务,如何打造AI分布式业务应用的技术底层?
|
4月前
|
数据可视化 Java API
Spring Boot与Swagger的集成
Spring Boot与Swagger的集成
|
4月前
|
Java API 开发者
在Spring Boot中集成Swagger API文档
在Spring Boot中集成Swagger API文档
|
1月前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
56 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
1月前
|
前端开发 Java 程序员
springboot 学习十五:Spring Boot 优雅的集成Swagger2、Knife4j
这篇文章是关于如何在Spring Boot项目中集成Swagger2和Knife4j来生成和美化API接口文档的详细教程。
109 1
|
2月前
|
前端开发 Java Spring
【非降版本解决】高版本Spring boot Swagger 报错解决方案
【非降版本解决】高版本Spring boot Swagger 报错解决方案
|
2月前
|
Java Spring
springboot 集成 swagger 2.x 和 3.0 以及 Failed to start bean ‘documentationPluginsBootstrapper‘问题的解决
本文介绍了如何在Spring Boot项目中集成Swagger 2.x和3.0版本,并提供了解决Swagger在Spring Boot中启动失败问题“Failed to start bean ‘documentationPluginsBootstrapper’; nested exception is java.lang.NullPointerEx”的方法,包括配置yml文件和Spring Boot版本的降级。
springboot 集成 swagger 2.x 和 3.0 以及 Failed to start bean ‘documentationPluginsBootstrapper‘问题的解决
下一篇
无影云桌面