关于java:Spring-Boot-自动配置的原理核心注解以及利用自动配置实现了自定义-Starter-组件

32次阅读

共计 19257 个字符,预计需要花费 49 分钟才能阅读完成。

本章内容

  1. 自定义属性疾速入门
  2. 外化配置
  3. 主动配置
  4. 自定义创立 Starter 组件

摘录:读书是读完这些文字还要好好用心去想想,写书也一样,做任何事也一样

图 2 第二章目录结构图

第 2 章 Spring Boot 配置

Spring Boot 配置,包含主动配置和外化配置。本章先实现自定义属性工程,将属性外化配置在 application.properties 利用配置文件,而后在工程中获取该属性值。接着会具体介绍属性的获取形式、外化配置和主动配置。最初会介绍利用主动配置自定义 Start 组件。

2.1 疾速入门工程

第一章的 HelloBookController 管制层中,在代码中以硬编码的形式应用字符串示意书信息。上面把书的信息作为属性,外化配置在 application.properties。益处是将利用参数、业务参数或第三方参数等对立配置在利用配置文件中,防止配置侵入业务代码,达到可配置的形式,不便及时调整批改。

2.1.1 配置属性

新建工程命名为 chapter-2-spring-boot-config,在 application.properties 中配置书名和作者,配置如下:

## 书信息
demo.book.name=[Spring Boot 2.x Core Action]
demo.book.writer=BYSocket

.properties 文件的每行参数被存储为一对字符串,即一个存储参数名称,被称为键;另一个为值。个别称为键值对配置。井号(#)或者英文状态下的叹号(!)作为第一行中第一个非空字符来示意该行的文本为正文。另外,反斜杠()用于转义字符。

Spring Boot 反对并举荐应用 YAML 格局的配置文件,将 application.properties 文件替换成 application.yml 文件,并配置雷同的属性,配置如下:

## 书信息
demo:
    book:
        name:《Spring Boot 2.x 核心技术实战 - 上 根底篇》writer: 泥瓦匠 BYSocket

YAML 是一个可读性高,用来表白数据序列的格局。示意键值对格局时,留神键和值由冒号及空白字符离开。强调下,空白字符是必须的,IDE 个别也会提醒。两种配置形式都十分便捷,在开发中抉择 .properties 或 .yml 文件配置。但如果两种配置文件同时存在的时候,默认优先应用 .properties 配置文件。YAML 与 .properties 配置文件对比方图 2-1 所示:

图 2-1 YAML 与 .properties 配置文件比照

留神:

在 application.properties 配置中文值,读取时会呈现中文乱码问题。因为 Java .properties 文件默认编码方式是 iso-8859,Spring Boot 利用以 UTF-8 的编码方式读取,就导致呈现乱码问题。

官网 Issue 中的解决办法是,将 .properties 文件中配置的中文值本义成 Unicode 编码模式。例如 demo.book.writer= 泥瓦匠 应该配置成 demo.book.writer=\u6ce5\u74e6\u5320。利用 IDEA properties 插件 或利用 Java 文件转码工具 native2ascii 来疾速地进行本义。该工具有在线版实现,地址如下:
https://javawind.net/tools/na…

2.1.2 创立属性类

在工程中新建包目录 demo.springboot.config,并在目录中创立名为 BookProperties 的属性类,代码如下:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * 书属性
 */
@Component
public class BookProperties {

    /**
     * 书名
     */
    @Value("${demo.book.name}")
    private String name;

    /**
     * 作者
     */
    @Value("${demo.book.writer}")
    private String writer;

    // ... 省略 getter / setter 办法
}

利用 @Component 注解定义了书的属性 Bean,并通过 @Value 注解为该 Bean 的成员变量(或者办法参数)主动注入 application.properties 文件的属性值。@Value 注解是通过“${propName}”的模式援用属性,propName 示意属性名称。

外围注解的知识点:

  • @Component 注解:

@Component 对类进行标注,职责是泛指组件 Bean,利用启动时会被容器加载并退出容器治理。常见的 @Controller@Service@Repository@Component 的分类细化组件,别离对应管制层、服务层、长久层的 Bean。

  • @Value 注解:

@Value 对 Bean 的字段或者办法参数进行标注,职责是基于表达式给字段或办法参数设置默认属性值。通常格局是注解 + SpEL 表达式,如 @Value("SpEL 表达式")

应用 @Vlaue 注解来援用属性值时,确保所援用的属性值在 application.properties 文件存在并且绝对应匹配,否则会造成 Bean 的创立谬误,引发 java.lang.IllegalArgumentException 非法参数异样。

2.1.3 获取属性

批改原有的 HelloBookController 类,通过注入的形式获取书属性 Bean 并返回。代码如下:

import demo.springboot.config.BookProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloBookController {

    @Autowired
    BookProperties bookProperties;

    @GetMapping("/book/hello")
    public String sayHello() {return "Hello," + bookProperties.getWriter() + "is writing"
                + bookProperties.getName() + "!";}
}

通过 @Autowired 注解标记在 BookProperties 字段,管制层主动拆卸属性 Bean 并应用。默认状况下要求被注解的 Bean 必须存在,须要容许 NULL 值,能够设置其 required 属性为 false:@Autowired(required = false)

2.1.4 运行工程

执行 ConfigApplication 类启动,在控制台看到胜利运行的输入后,关上浏览器拜访 /book/hello 地址,能够看到如图 2-2 所示的返回后果:

图 2-2 Hello Book 页面

也能够通过单元测试的形式验证属性获取是否胜利,单元测试具体相干的会在第 9 章节介绍。单元测试代码如下:

import demo.springboot.config.BookProperties;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ConfigApplicationTests {
    @Autowired
    BookProperties bookProperties;

    @Test
    public void testBookProperties() {Assert.assertEquals(bookProperties.getName(),"'Spring Boot 2.x Core Action'");
        Assert.assertEquals(bookProperties.getWriter(),"BYSocket");
    }
}

2.2 配置属性的获取形式

配置属性的罕用获取形式有基于 @Value@ConfigurationProperties 注解两种形式。两种形式适宜的场景不同,上面具体介绍其应用办法和场景。

2.2.1 @Value 注解

@Value 注解对 Bean 的变量或者办法参数进行标注,职责是基于表达式给字段或办法参数设置默认属性值。通常格局是注解 + SpEL 表达式,如 @Value("SpEL 表达式"),并标注在对应的字段或者办法上方,且必须对变量一一标注。这种形式实用于小而不简单的属性构造。属性结构复杂,字段很多的状况下,这种形式会比拟繁琐,应该思考应用 @ConfigurationProperties 注解。

另外通过 @PropertySource 注解引入对应门路的其余 .properties 文件。将书信息重新配置在 classpath 下新的 book.properties 配置文件后,读取新配置文件的代码如下:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

/**
 * 书属性
 */
@Component
@PropertySource("classpath:book.properties")
public class BookProperties {

    /**
     * 书名
     */
    @Value("${demo.book.name}")
    private String name;

    /**
     * 作者
     */
    @Value("${demo.book.writer}")
    private String writer;

    // ... 省略 getters / setters 办法
}

2.2.2 @ConfigurationProperties 注解

在包目录 demo.springboot.config 中创立名为 BookComponent 的属性类,并应用 @ConfigurationProperties 注解获取属性,代码如下:

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 书属性
 *
 */
@Component
@ConfigurationProperties(prefix = "demo.book")
public class BookComponent {

    /**
     * 书名
     */
    private String name;

    /**
     * 作者
     */
    private String writer;

    // ... 省略 getters / setters 办法
}

相似 @Value 注解形式,应用 @ConfigurationProperties(prefix = "demo.book") 注解标注在类上方能够达到雷同的成果。@ConfigurationProperties 注解的 prefix 是指定属性的参数名称。会匹配到配置文件中“demo.book.”构造的属性,星号“”是指会一一对应匹配 BookComponent 类的字段名。例如,字段 name 示意书名,会匹配到 demo.book.name 属性值。

@Value 注解形式强制字段必须对应在配置文件,@ConfigurationProperties 注解形式则不是必须的。个别状况下,所有字段应该保障一一对应在配置文件。如果没有属性值对应的话,该字段默认为空,@ConfigurationProperties 注解形式也不会引发任何异样,Spring Boot 举荐应用 @ConfigurationProperties 注解形式获取属性。

同样应用单元测试验证获取属性是否胜利。单元测试代码如下:

@Autowired
BookComponent bookComponent;

@Test
public void testBookComponent() {Assert.assertEquals(bookComponent.getName(),"'Spring Boot 2.x Core Action'");
    Assert.assertEquals(bookComponent.getWriter(),"BYSocket");
}
API org.springframework.boot.context.properties.ConfigurationProperties 注解参数
  • prefix

字符串值,绑定该名称前缀的属性对象。

  • value

字符串值,性能同 prefix 参数。

  • ignoreInvalidFields

布尔值,默认 false。绑定对象时,疏忽有效字段。

  • ignoreUnknownFields

布尔值,默认 true。绑定对象时,疏忽未知字段。

2.2.3 @ConfigurationProperties 数据验证

@ConfigurationProperties 注解形式反对验证性能,即当属性类被 @Validated 注解标注时,Spring Boot 初始化时会验证类的字段。在类的字段上增加 JSR-303 束缚注解,进行数据验证。上面为书属性字段增加非 NULL 和字符串非空束缚,代码如下:

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;

/**
 * 书属性
 *
 */
@Component
@ConfigurationProperties(prefix = "demo.book")
@Validated
public class BookComponent {

    /**
     * 书名
     */
    @NotEmpty
    private String name;

    /**
     * 作者
     */
    @NotNull
    private String writer;

    // ... 省略 getters / setters 办法
}

通过 @Validated 注解开启对 BookComponent 类字段的数据验证,如果 name 字段为 NULL 或者为空字符串时,会引发 BindValidationException 绑定数据验证异样。数据验证罕用在邮箱格局或者有长度限度的属性字段。另外,验证嵌套属性的值,必须在嵌套对象字段上方标注 @Valid 注解,用来触发其验证。例如,在书属性中新增嵌套对象出版社 Publishing,就须要在该对象上方标注 @Valid 注解,来开启对 Publishing 对象的数据验证。综上,两种属性获取形式各有优缺点,对比方图 2-3 所示:

图 2-3 @ConfigurationPropertiesd vs @Value

2.3 外化配置

Spring Boot 能够将配置内部化,即拆散存储在 classpath 之外,这种模式叫做“外化配置”。罕用在不同环境中,将配置从代码中拆散外置,只有简略地批改下外化配置,能够仍旧运行雷同的利用代码。外化配置表现形式不单单是 .properties 和 .yml 属性文件,还能够应用环境变量和命令行参数等来实现。那么,多处配置了雷同属性时,Spring Boot 是通过什么形式来管制外化配置的抵触呢?答案是外化配置优先级。

2.3.1 外化配置优先级

用命令行配置去笼罩 .properties 文件配置办法很简略。失常状况下利用 Java 命令运行工程,代码如下:

// chapter-2-spring-boot-config 目录下运行
java -jar target/chapter-2-spring-boot-config-1.0.jar

上面将书的作者信息 BYSocket 改成 Jeff,通过命令行配置笼罩属性,代码如下:

java -jar target/chapter-2-spring-boot-config-1.0.jar --demo.book.writer=Jeff

在命令行配置中,设置属性值的格局是用两个间断的减号“–”标记属性。在控制台看到胜利运行的输入后,关上浏览器,拜访 /book/hello 地址,能够看到如图 2-4 所示的返回后果:

图 2-4 书信息被笼罩页面

通过命令行配置笼罩属性提供了十分大的作用与便利性,常见于应用 shell 脚本运行工程时,能够不便地批改工程运行的配置。

然而这就引发了一个问题,岂不让工程很有侵入性,如果凋谢这个性能,导致未知的平安问题。所以 Spring Boot 提供了屏蔽命令行属性值设置,在利用启动类中设置 setAddCommandLineProperties 办法为 false,用于敞开命令行配置性能,代码如下:

SpringApplication.setAddCommandLineProperties(false);

命令行配置属性的优先级是第四。外化配置获取属性时,会按优先级从高到低获取。如果高优先级存在属性,则返回属性,并疏忽优先级低的属性。优先级如下:

  1. 本地 Devtools 全局配置
  2. 测试时 @TestPropertySource 注解配置
  3. 测试时 @SpringBootTest 注解的 properties 配置
  4. 命令行配置
  5. SPRING_APPLICATION_JSON 配置
  6. ServletConfig 初始化参数配置
  7. ServletContext 初始化参数配置
  8. Java 环境的 JNDI 参数配置
  9. Java 零碎的属性配置
  10. OS 环境变量配置
  11. 只能随机属性的 RandomValuePropertySource 配置
  12. 工程 jar 之外的多环境配置文件(application- {profile}.properties 或 YAML)
  13. 工程 jar 之内的多环境配置文件(application- {profile}.properties 或 YAML)
  14. 工程 jar 之外的利用配置文件(application.properties 或 YAML)
  15. 工程 jar 之内的利用配置文件(application.properties 或 YAML)
  16. @Configuration 类中的 @PropertySource 注解配置
  17. 默认属性配置(SpringApplication.setDefaultProperties 指定)

2.3.2 属性援用

在 application.properties 中配置属性时,属性之间能够间接通过“${propName}”的模式援用其余属性。比方新增书的形容 description 属性,代码如下:

## 书信息
demo.book.name=[Spring Boot 2.x Core Action]
demo.book.writer=BYSocket
demo.book.description=${demo.book.writer}'s${demo.book.name}

demo.book.description 属性援用了后面定义的 demo.book.name 和 demo.book.writer 属性,其值为 BYSocket’s[Spring Boot 2.x Core Action]。一方面能够使雷同配置能够复用,另一方面加强了配置的浏览性。

2.3.3 应用随机数

在 application.properties 中配置属性时,能够应用随机数配置,例如注入某些密钥、UUID 或者测试用例,须要每次不是一个固定的值。RandomValuePropertySource 类随机提供整形、长整形数、UUID 或者字符串。应用代码如下:

my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}

2.3.4 多环境配置

多环境是指不同配置的生产服务器应用同一工程代码部署,比方:开发环境、测试环境、预发环境、生产环境等。各个环境的工程端口、数据库配置、Redis 配置、日志配置等都会不同,传统模式下须要批改配置,工程从新编译打包,并部署到指定环境服务器。后果是容易产生配置谬误,导致开发部署效率低下。Spring Boot 应用多环境配置去解决这个问题。

多环境配置,相似 Maven 构建配置文件的思路,即配置多个不同环境的配置文件,再通过 spring.profiles.active 命令去指定读取特定配置文件的属性。多环境配置文件是不同于 application.properties 利用配置文件。多环境配置文件的约定命名格局为 application-{profile}.properties。多环境配置性能默认为激活状态,如果其余配置未被激活,则 {profile} 默认为 default,会加载 application-default.properties 默认配置文件,没有该文件就会加载 application.properties 利用配置文件。

多环境配置文件的属性读取形式和从 application.properties 利用配置文件读取形式统一。不论多环境配置文件在工程 jar 包内还是包外,依照配置优先级笼罩其余配置文件。在微服务实际开发中,常常会应用一个相似 deploy 工程去治理配置文件和打包其余业务工程。

在 application.properties 同级目录中,新建 application-dev.properties 作为开发环境配置文件,配置如下:

## 书信息
demo.book.name=[Spring Boot 2.x Core Action]  From Dev
demo.book.writer=BYSocket

新建 application-prod.properties 作为生产环境配置文件,代码如下:

## 书信息
demo.book.name=<Spring Boot 2.x Core Action Dev> From Prod
demo.book.writer=BYSocket

通过命令行指定读取 dev 环境配置文件并运行工程,代码如下:

java -jar target/chapter-2-spring-boot-config-1.0.jar --spring.profiles.active=dev

在多个环境配置中,通过命令 --spring.profiles.active=dev 指定读取某个配置文件,将 dev 更改成 prod,轻松切换读取生产环境配置。也能够在控制台的日志中确定配置读取来自 dev:

2017-11-09 12:10:52.978  INFO 72450 --- [main] demo.springboot.ConfigApplication        : The following profiles are active: dev

最初关上浏览器,拜访 /book/hello 地址,能够看到如图 2-5 所示的返回后果:

图 2-5 dev 环境书信息页面

2.4 主动配置

Spring Boot spring-boot-autoconfigure 依赖实现了默认的配置项,即利用默认值。这种模式叫做“主动配置”。Spring Boot 主动配置会依据增加的依赖,主动加载依赖相干的配置属性并启动依赖。例如默认用的内嵌式容器是 Tomcat,端口默认设置为 8080。

为什么须要主动配置?顾名思义,主动配置的意义是利用这种模式代替了配置 XML 繁琐模式。以前应用 Spring MVC,须要进行配置组件扫描、调度器、视图解析器等,应用 Spring Boot 主动配置后,只须要增加 MVC 组件即可主动配置所须要的 Bean。所有主动配置的实现都在 spring-boot-autoconfigure 依赖中,包含 Spring MVC、Data 和其它框架的主动配置。

2.4.1 spring-boot-autoconfigure 依赖

spring-boot-autoconfigure 依赖,是 Spring Boot 实现主动配置的外围 Starter 组件。其实现源码包构造如图 2-6 所示:

图 2-6 spring-boot-autoconfigure 依赖包目录

从图中能够看出,其中常见外围的包如下:

org.springframework.boot.autoconfigure
org.springframework.boot.autoconfigure.data.jpa
org.springframework.boot.autoconfigure.thymeleaf
org.springframework.boot.autoconfigure.web.servlet
org.springframework.boot.autoconfigure.web.reactive
... 省略 

在各自包目录下有对应的主动配置类,代码如下:

JpaRepositoriesAutoConfiguration 
ThymeleafAutoConfiguration
WebMvcAutoConfiguration
WebFluxAutoConfiguration
... 省略 

下面主动配置类顺次是 Jpa 主动配置类、Thymeleaf 主动配置类、Web MVC 主动配置类和 WebFlux 主动配置类。WebFlux 响应式框架会在第 3 章 具体介绍应用。

spring-boot-autoconfigure 职责是通过 @EnableAutoConfiguration 外围注解,扫描 ClassPath 目录中主动配置类对应依赖,并按肯定规定获取默认配置并主动初始化所须要的 Bean。在 application.properties 配置文件也能够批改默认配置项,罕用配置清单地址如下:

https://docs.spring.io/spring…

2.4.2 @EnableAutoConfiguration 注解

主动配置工作机制是通过 @EnableAutoConfiguration 注解中 @ImportAutoConfigurationImportSelector 主动配置导入选择器类实现的。查阅源码可得具体流程如下:

  • AutoConfigurationImportSelector 通过 SpringFactoriesLoader.loadFactoryNames() 外围办法读取 ClassPath 目录上面的 META-INF/spring.factories 文件。
  • spring.factories 文件中配置的 Spring Boot 主动配置类,例如常见的 WebMvcAutoConfiguration Web MVC 主动配置类和 ServletWebServerFactoryAutoConfiguration 容器主动配置类。
  • spring.factories 文件和 application.properties 文件都属于配置文件,配置的格局均为键值对。外面配置的每个主动配置类都会定义相干 Bean 的实例配置,也会定义什么条件下主动配置和哪些 Bean 被实例化。
  • 当 pom.xml 增加某 Starter 依赖组件的时候,就会主动触发该依赖的默认配置。

例如增加 spring-boot-starter-web 依赖后,启动利用会触发容器主动配置类。容器主动配置类 ServletWebServerFactoryAutoConfiguration 的局部代码如下:

package org.springframework.boot.autoconfigure.web.servlet;

@Configuration
@ConditionalOnClass({ServletRequest.class})
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties({ServerProperties.class})
@Import({ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class})
public class ServletWebServerFactoryAutoConfiguration {... 省略}

下面代码中,@ConditionalOnClass 注解示意对应的 ServletRequest 类在 ClassPath 目录上面存在,并且 @ConditionalOnWebApplication 注解示意该利用是 Servlet Web 利用时,才会去启动容器主动配置,并通过 ServerProperties 类默认设置了端口为 8080。Type.SERVLET 枚举代表 Servlet Web 利用,Type.REACTIVE 枚举代表响应式 WebFlux 利用。

主动配置,是一把双刃剑。用好了就像天下文治唯快不破一样。但要留神一些自动化配置造成的问题。常见的问题有:

  • Spring Boot 工程增加某些 Starter 组件依赖,又不须要触发组件主动配置
  • Spring Boot 配置多个不同数据源配置时,应用 XML 配置多数据源,但其默认数据源配置会触发主动配置呈现问题。

相似场景下,解决形式是通过 exclude 属性指定并排除主动配置类,代码如下:

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})

也等价于配置 @EnableAutoConfiguration 注解,代码如下:

@SpringBootApplication
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})

主动配置会最大的智能化,只有配置了 exclude 属性时,Spring Boot 优先初始化用户定义的 Bean,而后再进行主动配置。

2.4.3 利用主动配置自定义 Starter 组件

当公司须要共享或者开源 Spring Boot Starter 组件依赖包,就能够利用主动配置自定义 Starter 组件。一个残缺的 Starter 组件包含以下两点:

  • 提供主动配置性能的主动配置模块。
  • 提供依赖关系治理性能的组件模块,即封装了组件所有性能,开箱即用。

实现自定义 Starter 组件,并不会将这两点严格辨别,能够将主动配置性能和依赖治理联合在一起实现。上面利用主动配置实现自定义 Starter 组件:spring-boot-starter-swagger 组件是用来疾速生成 API 文档,简化原生应用 Swagger2。

spring-boot-starter-swagger 组件为 Spring For All 社区(spring4all.com)开源我的项目,源代码地址是 https://github.com/SpringForA…。

什么是 Swagger2

Swagger2 是 API 最大的开发框架,基于 OpenAPI 标准(OAS),治理了 API 整个生命周期,即从 API 设计到文档,从测试到部署。具体更多理解见其官网,https://swagger.io。

spring-boot-starter-swagger 组件依赖

创立一个新的 Spring Boot 工程,命名为 spring-boot-starter-swagger。在 pom.xml 配置相干

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>${version.swagger}</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>${version.swagger}</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-bean-validators</artifactId>
            <version>${version.swagger}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.12</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    

配置中增加了 spring-boot-starter 组件依赖用于主动配置个性,springfox-swagger2 依赖是 Swagger2 框架。

Swagger2 属性配置类 SwaggerProperties

新建名为 SwaggerProperties Swagger2 属性配置类,蕴含了所有默认属性值。应用该组件时,能够在 application.properties 配置文件配置对应属性项,进行笼罩默认配置。代码如下:

import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import springfox.documentation.schema.ModelRef;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Data
@ConfigurationProperties("swagger")
public class SwaggerProperties {

    /** 是否开启 swagger**/
    private Boolean enabled;

    /** 题目 **/
    private String title = "";
    /** 形容 **/
    private String description = "";
    /** 版本 **/
    private String version = "";
    /** 许可证 **/
    private String license = "";
    /** 许可证 URL**/
    private String licenseUrl = "";
    /** 服务条款 URL**/
    private String termsOfServiceUrl = "";

    private Contact contact = new Contact();

    /**swagger 会解析的包门路 **/
    private String basePackage = "";

    /**swagger 会解析的 url 规定 **/
    private List<String> basePath = new ArrayList<>();
    /** 在 basePath 根底上须要排除的 url 规定 **/
    private List<String> excludePath = new ArrayList<>();

    /** 分组文档 **/
    private Map<String, DocketInfo> docket = new LinkedHashMap<>();

    /**host 信息 **/
    private String host = "";

    /** 全局参数配置 **/
    private List<GlobalOperationParameter> globalOperationParameters;

     ... 省略,具体代码见 GitHub
}

@ConfigurationProperties(prefix = "swagger") 标注在类上方是指定属性的参数名称为 swagger。会对应匹配到配置文件中“swagger.*”构造的属性,例如,字段题目 title 示意题目,会匹配到 swagger.title 属性值。

Swagger2 主动配置类 SwaggerAutoConfiguration

新建名为 SwaggerAutoConfiguration Swagger2 主动配置类,提供 Swagger2 依赖关系治理性能和主动配置性能。代码如下:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;

@Configuration
@ConditionalOnProperty(name = "swagger.enabled", matchIfMissing = true)
@Import({
        Swagger2DocumentationConfiguration.class,
        BeanValidatorPluginsConfiguration.class
})
public class SwaggerAutoConfiguration implements BeanFactoryAware {

    private BeanFactory beanFactory;

    @Bean
    @ConditionalOnMissingBean
    public SwaggerProperties swaggerProperties() {return new SwaggerProperties();
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(name = "swagger.enabled", matchIfMissing = true)
    public List<Docket> createRestApi(SwaggerProperties swaggerProperties) {... 省略,具体代码见 GitHub}

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

下面代码实现流程如下:

  1. @Configuration 注解标注在类上方,表明该类为配置类。
  2. @Import 注解引入 Swagger2 提供的配置类 Swagger2DocumentationConfiguration 和 Bean 数据验证插件配置类 BeanValidatorPluginsConfiguration
  3. @ConditionalOnMissingBean 注解标注了两处办法,当 Bean 没有被创立时会执行被标注的初始化办法。第一处被标记办法是 swaggerProperties(),用来实例化属性配置类 SwaggerProperties; 第二处被标记办法是 createRestApi(),用来实例化 Swagger2 API 映射的 Docket 列表对象。
  4. @ConditionalOnProperty 注解标注在 createRestApi() 办法,name 属性会去查看环境配置项 swagger.enabled。默认状况下,属性存在且不是 false 的状况下,会触发该初始化办法。matchIfMissing 属性默认值为 false,这里设置为 true,示意如果环境配置项没被设置,也会触发。
Swagger2 启动注解类 EnableSwagger2Doc

新建名为 EnableSwagger2Doc Swagger2 启动注解类,用于开关 spring-boot-starter-swagger 组件依赖。代码如下:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({SwaggerAutoConfiguration.class})
public @interface EnableSwagger2Doc {}

下面代码 @Import 注解引入 Swagger2 主动配置类 SwaggerAutoConfiguration。当将该注解配置在利用启动类上方,即可开启 Swagger2 主动配置及其性能。

应用 spring-boot-starter-swagger 组件依赖

下面简略介绍了 spring-boot-starter-swagger 组件的外围代码实现,同样应用形式也很简略。在 chapter-2-spring-boot-config 工程的 Maven 配置中增加对应的依赖配置,目前反对 1.5.0.RELEASE 以上版本,配置如下:

<!-- 自定义 swagger2 Starter 组件依赖 -->
<dependency>
    <groupId>com.spring4all</groupId>
    <artifactId>spring-boot-starter-swagger</artifactId>
    <version>2.0</version>
</dependency>

另外,须要在 ConfigApplication 利用启动类上方配置启动注解类 EnableSwagger2Doc,代码如下:

import com.spring4all.swagger.EnableSwagger2Doc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@EnableSwagger2Doc // 开启 Swagger
@SpringBootApplication
public class ConfigApplication {public static void main(String[] args) {SpringApplication.run(ConfigApplication.class, args);
    }
}

执行 ConfigApplication 类启动,在控制台看到胜利运行的输入后,关上浏览器拜访 localhost:8080/swagger-ui.html 地址,能够看到主动生成的 Swagger API 文档,如图 2-7 所示:

图 2-7 Swagger API 文档

API org.springframework.boot.autoconfigure.EnableAutoConfiguration 注解参数
  • exclude:

Class 数组,排除特定的主动配置类。

  • excludeName:

字符串数组,排除特定名称的主动配置类。

API org.springframework.boot.autoconfigure.ConditionalOnProperty 注解参数
  • havingValue:

字符串,属性期望值是否匹配。

  • matchIfMissing:

布尔值,如果该属性值未设置,则匹配。

  • name:

字符串数组,要测试的属性名。

  • prefix:

字符串,属性前缀名。

  • value:

字符串,性能同 name。

API org.springframework.boot.autoconfigure.ConditionalOnClass 注解参数
  • name:

字符串数组,类名必须存在。

  • value:

Class 数组,类必须存在。

API org.springframework.boot.autoconfigure.ConditionalOnMissingBean 注解参数
  • annotation:

注解 Class 数组,匹配注解装璜的 Bean。

  • ignored:
    Class 数组,匹配时,疏忽该类型的 Bean。
  • ignoredType:

字符串数组,匹配时,疏忽该类型名称的 Bean。

  • name:

字符串数组,匹配要查看的 Bean 名称。

  • search:

SearchStrategy 对象,通过 SearchStrategy 来决定程序的上下文策略。

  • type:

字符串史胡族,匹配要查看的 Bean 类型名称。

  • value:

Class 数组,匹配要查看的 Bean 类型。

API org.springframework.boot.autoconfigure.ConditionalOnWebApplication 注解参数
  • type:

ConditionalOnWebApplication.Type 对象,匹配对应的 Web 应用程序类型。

2.5 本章小结

本章从自定义属性疾速入门工程登程,介绍了两种配置文件以及属性的获取形式,而后解说了外化配置的优先级、属性援用、随机式应用和多环境配置,最初解说了主动配置的原理、外围注解以及利用主动配置实现了自定义 Starter 组件。下一章介绍 Spring Boot Web 开发相干。

本章示例代码地址:https://github.com/JeffLi1993…

本文由博客群发一文多发等经营工具平台 OpenWrite 公布

正文完
 0