Spring Boot 提供了两种常用的配置文件, 分别是 properties 文件和 yml 文件. 他们的作用都是修改 Spring Boot 自动配置的默认值. 相对于 properties 文件而言, yml 文件更年轻, 也有很多的坑. 可谓成也萧何败萧何, yml 通过空格来确定层级关系, 是配置文件结构跟清晰, 但也会因为微不足道的空格而破坏了层级关系. 本章重点介绍 yml 的语法和从配置文件中取值. 还在等什么, 赶快来学习吧!
技术: yaml,properties 语法, ConfigurationProperties 和 Value 注解的使用, 配置文件占位符的使用
说明: 本章重点介绍 yaml 的语法和 ConfigurationProperties 注解的使用, 测试代码和完整代码请移步 github, 喜欢的朋友可以点个 star.
源码: https://github.com/ITDragonBlog/daydayup/tree/master/SpringBoot/spring-boot-yml
文章目录结构:
一, YAML 简介
yml 是 YAML(YAML Ain't Markup Language)语言的文件, 以数据为中心, 比 json,xml 等更适合做配置文件
yml 和 xml 相比, 少了一些结构化的代码, 使数据更直接, 一目了然.
yml 和 json 呢? 没有谁好谁坏, 合适才是最好的. yml 的语法比 json 优雅, 注释更标准, 适合做配置文件. json 作为一种机器交换格式比 yml 强, 更适合做 api 调用的数据交换.
一)YAML 语法
以空格的缩进程度来控制层级关系. 空格的个数并不重要, 只要左边空格对齐则视为同一个层级. 注意不能用 tab 代替空格. 且大小写敏感. 支持字面值, 对象, 数组三种数据结构, 也支持复合结构.
字面值: 字符串, 布尔类型, 数值, 日期. 字符串默认不加引号, 单引号会转义特殊字符. 日期格式支持 yyyy/MM/dd HH:mm:ss
对象: 由键值对组成, 形如 key:(空格)value 的数据组成. 冒号后面的空格是必须要有的, 每组键值对占用一行, 且缩进的程度要一致, 也可以使用行内写法:{k1: v1, ....kn: vn}
数组: 由形如 -(空格)value 的数据组成. 短横线后面的空格是必须要有的, 每组数据占用一行, 且缩进的程度要一致, 也可以使用行内写法: [1,2,...n]
复合结构: 上面三种数据结构任意组合
二)YAML 的运用
创建一个 Spring Boot 的全局配置文件 application.yml, 配置属性参数. 主要有字符串, 带特殊字符的字符串, 布尔类型, 数值, 集合, 行内集合, 行内对象, 集合对象这几种常用的数据格式.
yaml:
str: 字符串可以不加引号
- specialStr: "双引号直接输出 \ n 特殊字符"
- specialStr2: '单引号可以转义 \ n 特殊字符'
- flag: false
- num: 666
- Dnum: 88.88
- list:
- - one
- - two
- - two
- set: [1,2,2,3]
- map: {k1: v1, k2: v2}
- positions:
- - name: ITDragon
- salary: 15000.00
- - name: ITDragonBlog
- salary: 18888.88
创建实体类 YamlEntity.java 获取配置文件中的属性值, 通过注解 @ConfigurationProperties 获取配置文件中的指定值并注入到实体类中 mailto:通过注解@ConfigurationProperties获取配置文件中的指定值并注入到实体类中 . 其具体的测试方法和获取值的原理, 请继续往后看!
- import org.springframework.boot.context.properties.ConfigurationProperties;
- import org.springframework.stereotype.Component;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
- /**
- * YAML 语法实体类
- * 切记点:
- * 一, 冒号后面加空格, 即 key:(空格)value
- * 二, 每行参数左边空格数量决定了该参数的层级, 不可乱输入.
- */
- @Component
- @ConfigurationProperties(prefix = "yaml")
- public class YamlEntity {
- // 字面值, 字符串, 布尔, 数值
- private String str; // 普通字符串
- private String specialStr; // 转义特殊字符串
- private String specialStr2;// 输出特殊字符串
- private Boolean flag; // 布尔类型
- private Integer num; // 整数
- private Double dNum; // 小数
- // 数组, List 和 Set, 两种写法: 第一种:- 空格 value, 每个值占一行, 需缩进对齐; 第二种:[1,2,...n] 行内写法
- private List<Object> list; // list 可重复集合
- private Set<Object> set; // set 不可重复集合
- // Map 和实体类, 两种写法: 第一种: key 空格 value, 每个值占一行, 需缩进对齐; 第二种:{key: value,....} 行内写法
- private Map<String, Object> map; // Map K-V
- private List<Position> positions; // 复合结构, 集合对象
- // 省略 getter,setter,toString 方法
- }
三)YML 小结
一, 字符串可以不加引号, 若加双引号则输出特殊字符, 若不加或加单引号则转义特殊字符;
二, 数组类型, 短横线后面要有空格; 对象类型, 冒号后面要有空格;
三, YAML 是以空格缩进的程度来控制层级关系, 但不能用 tab 键代替空格, 大小写敏感;
四, 如何让一个程序员崩溃? 在 yml 文件中加几个空格!(>皿<)
二, Properties 简介
properties 文件大家经常用, 这里就简单介绍一下. 其语法结构形如: key=value. 注意中文乱码问题, 需要转码成 ASCII. 具体如下所示:
- userinfo.account=itdragonBlog
- userinfo.age=25
- userinfo.active=true
- userinfo.created-date=2018/03/31 16:54:30
- userinfo.map.k1=v1
- userinfo.map.k2=v2
- userinfo.list=one,two,three
userinfo.position.name=Java 架构师
userinfo.position.salary=19999.99
从配置文件中取值注入到实体类中, 和 YAML 是一样的.
- import org.springframework.boot.context.properties.ConfigurationProperties;
- import org.springframework.stereotype.Component;
- import java.util.Date;
- import java.util.List;
- import java.util.Map;
- /**
- * 用户信息
- * @ConfigurationProperties : 被修饰类中的所有属性会和配置文件中的指定值 (该值通过 prefix 找到) 进行绑定
- */
- @Component
- @ConfigurationProperties(prefix = "userinfo")
- public class UserInfo {
- private String account;
- private Integer age;
- private Boolean active;
- private Date createdDate;
- private Map<String, Object> map;
- private List<Object> list;
- private Position position;
- // 省略 getter,setter,toString 方法
- }
三, 配置文件取值
Spring Boot 通过 ConfigurationProperties 注解从配置文件中获取属性. 从上面的例子可以看出 ConfigurationProperties 注解可以通过设置 prefix 指定需要批量导入的数据. 支持获取字面值, 集合, Map, 对象等复杂数据. ConfigurationProperties 注解还有其他特么呢? 它和 Spring 的 Value 注解又有什么区别呢? 带着这些问题, 我们继续往下看.(̀́)و
一)ConfigurationProperties 和 Value 优缺点
ConfigurationProperties 注解的优缺点
一, 可以从配置文件中批量注入属性;
二, 支持获取复杂的数据类型;
三, 对属性名匹配的要求较低, 比如 user-name,user_name,userName,USER_NAME 都可以取值;
四, 支持 JAVA 的 JSR303 数据校验;
五, 缺点是不支持强大的 SpEL 表达式;
Value 注解的优缺点正好相反, 它只能一个个配置注入值; 不支持数组, 集合等复杂的数据类型; 不支持数据校验; 对属性名匹配有严格的要求. 最大的特点是支持 SpEL 表达式, 使其拥有更丰富的功能.
二)@ConfigurationProperties 详解
第一步: 导入依赖. 若要使用 ConfigurationProperties 注解, 需要导入依赖 spring-boot-configuration-processor;
第二步: 配置数据. 在 application.yml 配置文件中, 配置属性参数, 其前缀为 itdragon, 参数有字面值和数组, 用来判断是否支持获取复杂属性的能力;
第三步: 匹配数据. 在类上添加注解 ConfigurationProperties, 并设置 prefix 属性值为 itdragon. 并把该类添加到 Spring 的 IOC 容器中.
第四步: 校验数据. 添加数据校验 Validated 注解, 开启数据校验, 测试其是否支持数据校验的功能;
第五步: 测试 ConfigurationProperties 注解是否支持 SpEL 表达式;
导入依赖: pom.xml 添加 spring-boot-configuration-processor 依赖
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-configuration-processor</artifactId>
- <optional>true</optional>
- </dependency>
配置数据: application.yml 配置属性参数, nick-name 是用来判断匹配属性的松散性, 若换成 nick_name 依然可以获取值.
- itdragon:
- nick-name: ITDragonBlog
- email: 1234567890@qq.com
- iphone: 1234567890
- abilities: [java, sql, html]
- created_date: 2018/03/31 15:27:30
匹配和校验数据:
- import org.springframework.boot.context.properties.ConfigurationProperties;
- import org.springframework.stereotype.Component;
- import org.springframework.validation.annotation.Validated;
- import javax.validation.constraints.Email;
- import java.util.Date;
- import java.util.List;
- /**
- * ConfigurationProperties 注解语法类
- * 第一步: 导入依赖 spring-boot-configuration-processor;
- * 第二步: 把 ConfigurationProperties 注解修饰的类添加到 Spring 的 IOC 容器中;
- * 第三步: 设置 prefix 属性, 指定需要注入属性的前缀;
- * 第四步: 添加数据校验注解, 开启数据校验;
- *
- * 注意点:
- * 一, nickName 和 createdDate 在 yml 配置文件中, 对应参数分别是中划线和下划线, 用于测试其对属性名匹配的松散性
- * 二, email 和 iphone 测试其支持 JSR303 数据校验
- * 三, abilities 测试其支持复杂的数据结构
- */
- @Component
- @ConfigurationProperties(prefix = "itdragon")
- @Validated
- public class ConfigurationPropertiesEntity {
- private String nickName; // 解析成功, 支持松散匹配属性
- private String email;
- // @Email // 解析失败, 数据校验成功: BindValidationException: Binding validation errors on itdragon
- private String iphone;
- private List<String> abilities;
- private Date createdDate; // 解析成功, 支持松散匹配属性
- // @ConfigurationProperties("#{(1+2-3)/4*5}")
- private String operator; // 语法报错, 不支持 SpEL 表达式: not applicable to field
- // 省略 getter,setter,toString 方法
- }
三)@Value 详解
上一篇博客已经介绍过 Value 注解的使用, 这里只简单说明.
第一步: 在属性上添加 Value 注解, 通过 ${}设置参数从配置文件中注入值;
第二步: 修改
${itdragon.ceatred_date}
中的参数值, 改为
${itdragon.ceatredDate}
测试是否能解析成功;
第三步: 添加数据校验 Validated 注解, 开启数据校验, 测试其是否支持数据校验的功能;
第四步: 测试 Value 注解是否支持 SpEL 表达式;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.stereotype.Component;
- import org.springframework.validation.annotation.Validated;
- import javax.validation.constraints.Email;
- import java.util.Date;
- import java.util.List;
- /**
- * Value 注解语法类
- * 第一步: 在属性上添加注解 Value 注入参数
- * 第二步: 把 Value 注解修饰的类添加到 Spring 的 IOC 容器中;
- * 第三步: 添加数据校验注解, 检查是否支持数据校验;
- *
- * 注意点:
- * 一, nickName 和 createdDate 在 yml 配置文件中, 对应参数分别是中划线和下划线, 用于测试其对属性名匹配的松散性
- * 二, email 和 iphone 测试其支持 JSR303 数据校验
- * 三, abilities 测试其支持复杂的数据结构
- *
- * 结论:
- * 一, createDate 取值必须和 yml 配置文件中的参数保持一致,
- * 二, 既是在 iphone 上添加邮箱验证注解依然可以通过测试,
- * 三, 不支持复杂的数据结构, 提示错误和第一条相同: IllegalArgumentException: Could not resolve placeholder 'itdragon.abilities' in value "${itdragon.abilities}"
- */
- @Component
- @Validated
- public class ValueEntity {
- @Value("${itdragon.nick-name}")
- private String nickName;
- @Value("${itdragon.email}")
- private String email;
- @Value("${itdragon.iphone}") // 解析成功, 并不支持数据校验
- private String iphone;
- // @Value("${itdragon.abilities}") // 解析错误, 并不支持复杂的数据结构
- private List<String> abilities;
- // @Value("${itdragon.ceatredDate}") // 解析错误, 并不支持松散匹配属性, 必须严格一致
- private Date createdDate;
- // Value 注解的强大一面: 支持 SpEL 表达式
- @Value("#{(1+2-3)/4*5}") // 算术运算
- private String operator;
- @Value("#{1>2 || 2 <= 3}") // 关系运算
- private Boolean comparison;
- @Value("#{systemProperties['java.version']}") // 系统配置: os.name
- private String systemProperties;
- @Value("#{T(java.lang.Math).abs(-18)}") // 表达式
- private String mapExpression;
- // 省略 getter,setter,toString 方法
- }
四)配置文件取值小结
一, ConfigurationProperties 注解支持批量注入, 而 Value 注解适合单个注入;
二, ConfigurationProperties 注解支持数据校验, 而 Value 注解不支持;
三, ConfigurationProperties 注解支持松散匹配属性, 而 Value 注解必须严格匹配属性;
四, ConfigurationProperties 不支持强大的 SpEL 表达式, 而 Value 支持;
四, 配置文件占位符
占位符和随机数比较简单, 这里就直接贴出代码. 需要注意的是:
一, 占位符的值必须是完整路径
二, 占位符设置默认值, 冒号后面不能有空格
- ran: # 这里的 prefix 不能是 random,
- ran-value: ${random.value}
- ran-int: ${random.int}
- ran-long: ${random.long}
- ran-int-num: ${random.int(10)}
- ran-int-range: ${random.int[10,20]}
ran-placeholder: placeholder_${ran.ran-value: 此处不能有空格, 且 key 为完整路径}
- import org.springframework.boot.context.properties.ConfigurationProperties;
- import org.springframework.stereotype.Component;
- /**
- * 随机数和占位符语法类
- */
- @Component
- @ConfigurationProperties(prefix = "ran")
- public class RandomEntity {
- private String ranValue; // 随机生成一个字符串
- private Integer ranInt; // 随机生成一个整数
- private Long ranLong; // 随机生成一个长整数
- private Integer ranIntNum; // 在指定范围内随机生成一个整数
- private Integer ranIntRange;// 在指定区间内随机生成一个整数
- private String ranPlaceholder;// 占位符
- // 省略 getter,setter,toString 方法 e
- }
测试代码:
- @RunWith(SpringRunner.class)
- @SpringBootTest
- public class SpringBootYmlApplicationTests {
- @Autowired
- private UserInfo userInfo;
- @Autowired
- private YamlEntity yamlEntity;
- @Autowired
- private ConfigurationPropertiesEntity configurationPropertiesEntity;
- @Autowired
- private ValueEntity valueEntity;
- @Autowired
- private RandomEntity randomEntity;
- @Test
- public void contextLoads() {
- // System.out.println("YAML Grammar :" + yamlEntity);
- // System.out.println("UserInfo :" + userInfo);
- // System.out.println("ConfigurationProperties Grammar :" + configurationPropertiesEntity);
- // System.out.println("Value Grammar :" + valueEntity);
- System.out.println("Random Grammar :" + randomEntity);
- }
- }
五, 总结
一, Spring Boot 支持两种格式的配置文件, 其中 YAML 的数据结构比 properties 更清晰.
二, YAML 是专门用来写配置文件的语言, 非常简洁和强大.
三, YAML 对空格的要求很严格, 且不能用 Tab 键代替.
四, YAML 通过空格缩进的程度确定层级, 冒号后面有空格, 短横线后面有空格.
五, ConfigurationProperties 注解适合批量注入配置文件中的属性, Value 注解适合获取配置文件中的某一项.
六, ConfigurationProperties 注解支持数据校验和获取复杂的数据, Value 注解支持 SpEL 表达式.
文章到这里就结束了. 如果文章对你有帮助, 可以点个 "推荐", 也可以 "关注" 我, 获得更多丰富的知识.
这里是博客文章目录一栏表中的部分内容, 如果有感兴趣的内容可以点击右边的链接: http://www.cnblogs.com/itdragon/p/8709948.html
来源: https://www.cnblogs.com/itdragon/p/8686554.html