二八佳人体似酥,腰间仗剑斩愚夫。虽然不见人头落,暗里教君骨髓枯。
上一章简单介绍了SpringBoot自定义banner,配置端口号和项目路径(二),如果没有看过,请观看上一章
一. 什么是YAML 配置文件
相比于 application.properties 配置文件,SpringBoot 更推荐使用 application.yml 的配置文件方式。
YAML 是 “YAML Ain’t Markup Language” 的递归缩写,是方便人类读写的一种格式,比JSON 格式还方便。
YAML 文件,采用 key–value的形式进行编写, value 可以是单个值,也可以是数组集合,也可以是对象。
properties 配置文件和yaml 配置文件,都是对以前的 *.xml 配置文件进行的简化。
一.一 Yaml 文件的优点
拿 MavenHelloWorld项目里面的配置端口号为 8027,配置项目路径为 /Lin 来看。
XML文件,就需要配置成:
<server>
<port>8027</port>
<servlet>
<context-path>/Lin</context-path>
</servlet>
</server>
Properties 文件,就需要配置成:
server.port=8027
server.servlet.context-path=/Lin
而 Yaml 文件只需要配置成:
server:
port: 8027
servlet:
context-path: /Lin
当配置文件过多时,如 datasource数据库,redis配置,mongodb配置,shiro配置,mybatis配置等, properties文件也难于理解和阅读了。
而yaml文件,目录结构层次清晰,易于理解和阅读。
下面老蝴蝶开始讲解 Yaml 配置文件。 为了便于观察 Yaml 配置文件的输出结果,
不采用直接写出结果的方式,而采用运行输出结果的方式,
需要创建一个 SpringBoot的 Yaml 项目。
二. 创建 Yaml 项目
根据 第一章的 Maven 创建SpringBoot项目的方式,创建一个名为 Yaml 的项目。里面有pom.xml 依赖,有启动类,有测试类,也有application.properties配置文件,banner.txt 文件,还有更重要的 application.yml 配置文件。
为了便于 Bean 对象的封装,在 pom.xml 里面引入了 lombok的依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
关于配置文件的格式配置,其实是定义在 Yaml工程的父项目 spring-boot-starter-parent-2.2.2.RELEASE.pom.xml 文件里面。
可以定义成 yml,也可以是 yaml, properties.
当同时存在,造成重突时, properties配置文件的优先级最高, yml 配置文件的的优先级最低。
二.一 验证 properties和 yaml配置文件的优先级
二.一.一 application.properties配置文件
server.port=8027
server.servlet.context-path=/Lin
二.二.二 application.yml 配置文件
server:
port: 8081
servlet:
context-path: /Yue
二.二.三 运行 YamlApplication 启动类,查看控制台输出
发现, application.properties 配置文件生效了。
将 application.properties 文件删除,只保留 application.yml 配置文件。
三. Yaml 配置文件的基本语法
三.一 基本规则
- 大小写敏感
- 使用缩进表示层级结构
- 缩进时,不使用 TAB 键进行缩进,只允许使用空格。
- 缩进时,不一定要是四个空格键,或者两个空格键,只需要保证同一层次下的元素左对齐就可以了。
- key: value 的值, : 与value 之间,需要有一个空格,进行分隔开来。
- 注释时,用 # 进行注释
三.二 放置基本的常量元素
# 放置基本的元素
name: 两个蝴蝶飞
age: 26
sex: 男
single: true
weight: 68.5
三.三 放置对象
# 放置对象
book:
name: 陌生人,我送你一首诗
author: 岳泽霖
nickName: 两个蝴蝶飞
三.四 放置数组
# 放置数组
hobby:
- 看书
- 写代码
- 写诗
- 写博客
三.五 单引号,双引号
# 放置特殊的字符串
str:
desc1: 我是两个蝴蝶\n飞 # 变成: 我是两个蝴蝶\n飞
desc2: "我是两个蝴蝶\n飞" # 会变成: 我是两个蝴蝶
# 飞
desc3: '我是两个蝴蝶\n飞' # 会变成: 我是两个蝴蝶\n飞
字符串,不用加 单引号,或者双引号。
双引号,不会进行转义,将 \n 变成换行回车
单引号,会进行转义, \n 还是\n.
三.六 合理的嵌套使用
book:
name: 陌生人,我送你一首诗
author: 岳泽霖
nickName: 两个蝴蝶飞
# 放置数组
hobby:
- 看书
- 写代码
- 写诗
- 写博客
info:
name: 两个蝴蝶飞
age: 26
sex: 男
single: true
weight: 68.5
这样,完全是合法的。
三.七 配置占位符
name2: 老蝴蝶 # 随机生成 uuid
age2: # 随机生成int范围内的值,-2^31~2^31-1
三.八 配置引用和默认值
info1: # 引入book对象里面的 author属性
info2: # 引用book对象里面的info属性,如果没有,取:后面的默认值,张三
四. 读取application.yml 里面的配置文件
四.一 构建基本的配置文件读取信息
# 放置基本的元素
name: 两个蝴蝶飞
single: false
age: 26
# 放置对象
book:
name: 陌生人,我送你一首诗
author: 岳泽霖
score: 0.00
hobby:
- 看书
- 写代码
- 写诗
- 写博客
addr:
四.二 采用 Bean 对象进行接收
在pojo 包下,新创建两个类用于接收数据
四.二.一 SingleInfo 类接收主体对象
@Data
public class SingleInfo {
private String name;
private Boolean single;
private Integer age;
private String addr;
private Book book;
}
四.二.二 Book 类接收书籍
@Data
public class Book {
private String name;
private String author;
private Double score;
private String[] hobby;
}
四.三 采用 Spring的 @Value 进行接收
四.三.一 添加组件注解和@Value注解
@Data
@Component
public class SingleInfo {
@Value("")
private String name;
@Value("")
private Boolean single;
@Value("")
private Integer age;
@Value("")
private String addr;
//暂时不处理
private Book book;
}
四.三.二 测试运行
@SpringBootTest
class YamlApplicationTests {
@Autowired
private SingleInfo singleInfo;
@Test
void contextLoads() {
System.out.println(singleInfo);
}
}
测试运行:
能够获取到相应的数据。
但是这种方式,需要对属性一个一个的封装。
book 没有添加相应的注解,故输出为 null
四.四 采用 @ConfigurationProperties 进行封装
四.四.一 在SingleInfo 类上面,添加 @ConfigurationProperties 注解
这个注解,一定要记住。 Configuration+Properties ,组成了 @ConfigurationProperties
Idea 提示让打开文档,那就打开文档,目前发现文档链接已经打不开了。
解决方案,添加 spring-boot-configuration-processor 依赖即可。
四.四.二 添加依赖
在 pom.xml 里面,添加 spring-boot-configuration-processor 依赖
<!-- 导入配置文件处理器,配置文件进行绑定就会有提示,需要重启 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
添加依赖之后,重启就好了。
四.四.三 测试运行
发现, book 属性也自动填充了,即使 Book 类没有添加 @Component 组件注解。
四.四.四 为 @ConfigurationProperties 添加前缀prefix
SingleInfo 一定提示:
但是我们这个类,前面没有任何前缀啊。 所以用 Book 类进行演示。
四.四.四.一 Book 类添加组件和@ConfigurationProperties 注解
@Component
@ConfigurationProperties(prefix = "book")
四.四.四.二 测试 Book类的自动填充
Book 正常的填充。
四.五 @PropertySource 注解进行封装
@ConfigurationProperties 并没有添加关于属性文件的配置信息,它怎么知道,要读取的是哪一个配置文件呢? 发现,我们将 yaml配置信息放置在了 application.yml(SpringBoot的全局配置文件), 答案就在这儿。
@ConfigurationProperties 会默认从全局配置文件中获取值
在 resoruces 下面,添加 myapplication.yml 配置文件,里面放置 四.一 里面的内容,并且从 application.yml 里面移除四.一里面的内容
四.五.一 测试验证,看是否读取了
Book 取消相应的注解。
SingleInfo 保持不变。
运行没有报错,但没有读取到相应的信息。
四.五.二 通过 @PropertySource 进行指定配置文件
通过 @PropertySource 注解指定文件路径时,就需要 用 @Value 一个个进行绑定属性,否则会无法绑定相应的属性。
运行程序, 发现运行成功了,但是会中文乱码。
@PropertySource 注解,支持添加 encoding 来指定编码。
@PropertySource(value = "classpath:myapplication.yml",encoding = "UTF-8")
添加encoding 属性后,继续运行程序:
乱码问题解决。
老蝴蝶为什么不演示 Book 绑定,或者在 SingleInfo 对象里面绑定 book呢? @Value属性,不支持这么绑定。
四.六 @ConfigurationProperties 与 @Value 注解比较
@ConfigurationProperties |
@Value |
|
功能 |
批量注入配置文件中的属性 |
需要一个个指定属性,分别绑定 |
松散绑定 |
支持 |
不支持 |
SpEL |
不支持 |
支持 |
JSR303数据校验 |
支持 |
不支持 |
复杂类型封装 |
支持 |
不支持 |
如果我们只需要获取到配置文件中某一个值的话,可以使用 @Value
如果需要获取到多个值的话,还与 JavaBean 进行绑定,最好使用 @ConfigurationProperties 。
本章节的代码放置在 github 上: