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,配置属性参数。主要有字符串,带特殊字符的字符串,布尔类型,数值,集合,行内集合,行内对象,集合对象这几种常用的数据格式。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
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获取配置文件中的指定值并注入到实体类中 。其具体的测试方法和获取值的原理,请继续往后看!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
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。具体如下所示:
1
2
3
4
5
6
7
8
9
|
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是一样的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
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依赖
1
2
3
4
5
|
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-configuration-processor</artifactid>
<optional> true </optional>
</dependency>
|
配置数据:application.yml 配置属性参数,nick-name是用来判断匹配属性的松散性,若换成nick_name依然可以获取值。
1
2
3
4
5
6
|
itdragon:
nick-name: itdragonblog
email: 1234567890 @qq .com
iphone: 1234567890
abilities: [java, sql, html]
created_date: 2018 / 03 / 31 15 : 27 : 30
|
匹配和校验数据:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
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表达式;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
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;
@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支持;
四、配置文件占位符
占位符和随机数比较简单,这里就直接贴出代码。需要注意的是:
一、占位符的值必须是完整路径
二、占位符设置默认值,冒号后面不能有空格
1
2
3
4
5
6
7
|
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为完整路径}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
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/8686554.html