Spring Boot配置文件详解
Posted zsh-blogs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Boot配置文件详解相关的知识,希望对你有一定的参考价值。
Spring Boot提供了两种常用的配置文件,分别是properties文件和yml文件。
一、yml配置方式
以空格的缩进程度来控制层级关系。空格的个数并不重要,只要左边空格对齐则视为同一个层级。注意不能用tab代替空格。且大小写敏感。支持字面值,对象,数组三种数据结构,也支持复合结构。
创建一个Spring Boot 的全局配置文件 application.yml,配置属性参数。主要有字符串,带特殊字符的字符串,布尔类型,数值,集合,行内集合,行内对象,集合对象这几种常用的数据格式。
yaml: str: 字符串可以不加引号 specialStr: "双引号直接输出 特殊字符" specialStr2: ‘单引号可以转义 特殊字符‘ 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 import org.springframework.boot.context.properties.ConfigurationProperties; 2 import org.springframework.stereotype.Component; 3 4 import java.util.List; 5 import java.util.Map; 6 import java.util.Set; 7 8 /** 9 * YAML 语法实体类 10 * 11 * 切记点: 12 * 一、冒号后面加空格,即 key:(空格)value 13 * 二、每行参数左边空格数量决定了该参数的层级,不可乱输入。 14 */ 15 16 @Component 17 @ConfigurationProperties(prefix = "yaml") 18 public class YamlEntity { 19 20 // 字面值,字符串,布尔,数值 21 private String str; // 普通字符串 22 private String specialStr; // 输出特殊字符串 23 private String specialStr2;// 转义特殊字符串 24 private Boolean flag; // 布尔类型 25 private Integer num; // 整数 26 private Double dNum; // 小数 27 28 // 数组,List和Set,两种写法: 第一种:-空格value,每个值占一行,需缩进对齐;第二种:[1,2,...n] 行内写法 29 private List<Object> list; // list可重复集合 30 private Set<Object> set; // set不可重复集合 31 32 // Map和实体类,两种写法:第一种:key空格value,每个值占一行,需缩进对齐;第二种:{key: value,....} 行内写法 33 private Map<String, Object> map; // Map K-V 34 private List<Position> positions; // 复合结构,集合对象 35 36 public String getStr() { 37 return str; 38 } 39 40 public void setStr(String str) { 41 this.str = str; 42 } 43 44 public String getSpecialStr() { 45 return specialStr; 46 } 47 48 public void setSpecialStr(String specialStr) { 49 this.specialStr = specialStr; 50 } 51 52 public String getSpecialStr2() { 53 return specialStr2; 54 } 55 56 public void setSpecialStr2(String specialStr2) { 57 this.specialStr2 = specialStr2; 58 } 59 60 public Boolean getFlag() { 61 return flag; 62 } 63 64 public void setFlag(Boolean flag) { 65 this.flag = flag; 66 } 67 68 public Integer getNum() { 69 return num; 70 } 71 72 public void setNum(Integer num) { 73 this.num = num; 74 } 75 76 public Double getdNum() { 77 return dNum; 78 } 79 80 public void setdNum(Double dNum) { 81 this.dNum = dNum; 82 } 83 84 public List<Object> getList() { 85 return list; 86 } 87 88 public void setList(List<Object> list) { 89 this.list = list; 90 } 91 92 public Set<Object> getSet() { 93 return set; 94 } 95 96 public void setSet(Set<Object> set) { 97 this.set = set; 98 } 99 100 public Map<String, Object> getMap() { 101 return map; 102 } 103 104 public void setMap(Map<String, Object> map) { 105 this.map = map; 106 } 107 108 public List<Position> getPositions() { 109 return positions; 110 } 111 112 public void setPositions(List<Position> positions) { 113 this.positions = positions; 114 } 115 116 @Override 117 public String toString() { 118 return "YamlEntity{" + 119 "str=‘" + str + ‘‘‘ + 120 ", specialStr=‘" + specialStr + ‘‘‘ + 121 ", specialStr2=‘" + specialStr2 + ‘‘‘ + 122 ", flag=" + flag + 123 ", num=" + num + 124 ", dNum=" + dNum + 125 ", list=" + list + 126 ", set=" + set + 127 ", map=" + map + 128 ", positions=" + positions + 129 ‘}‘; 130 } 131 }
测试用例在最下面。
二、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=Javau67B6u6784u5E08(Java架构师)
userinfo.position.salary=19999.99
从配置文件中取值注入到实体类中,和YAML是一样的。
1 package com.itdragon.entity; 2 3 import org.springframework.boot.context.properties.ConfigurationProperties; 4 import org.springframework.stereotype.Component; 5 6 import java.util.Date; 7 import java.util.List; 8 import java.util.Map; 9 10 /** 11 * 用户信息 12 * @ConfigurationProperties : 被修饰类中的所有属性会和配置文件中的指定值(该值通过prefix找到)进行绑定 13 */ 14 @Component 15 @ConfigurationProperties(prefix = "userinfo") 16 public class UserInfo { 17 18 private String account; 19 private Integer age; 20 private Boolean active; 21 private Date createdDate; 22 private Map<String, Object> map; 23 private List<Object> list; 24 private Position position; 25 26 public String getAccount() { 27 return account; 28 } 29 30 public void setAccount(String account) { 31 this.account = account; 32 } 33 34 public Integer getAge() { 35 return age; 36 } 37 38 public void setAge(Integer age) { 39 this.age = age; 40 } 41 42 public Boolean getActive() { 43 return active; 44 } 45 46 public void setActive(Boolean active) { 47 this.active = active; 48 } 49 50 public Date getCreatedDate() { 51 return createdDate; 52 } 53 54 public void setCreatedDate(Date createdDate) { 55 this.createdDate = createdDate; 56 } 57 58 public Map<String, Object> getMap() { 59 return map; 60 } 61 62 public void setMap(Map<String, Object> map) { 63 this.map = map; 64 } 65 66 public List<Object> getList() { 67 return list; 68 } 69 70 public void setList(List<Object> list) { 71 this.list = list; 72 } 73 74 public Position getPosition() { 75 return position; 76 } 77 78 public void setPosition(Position position) { 79 this.position = position; 80 } 81 82 @Override 83 public String toString() { 84 return "UserInfo{" + 85 "account=‘" + account + ‘‘‘ + 86 ", age=" + age + 87 ", active=" + active + 88 ", createdDate=" + createdDate + 89 ", map=" + map + 90 ", list=" + list + 91 ", position=" + position + 92 ‘}‘; 93 } 94 }
测试用例在最下面。
三、配置文件取值对比
一)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
匹配和校验数据:
1 package com.itdragon.entity; 2 3 import org.springframework.boot.context.properties.ConfigurationProperties; 4 import org.springframework.stereotype.Component; 5 import org.springframework.validation.annotation.Validated; 6 7 import javax.validation.constraints.Email; 8 import java.util.Date; 9 import java.util.List; 10 11 /** 12 * ConfigurationProperties 注解语法类 13 * 第一步:导入依赖 spring-boot-configuration-processor; 14 * 第二步:把ConfigurationProperties注解修饰的类添加到Spring的IOC容器中; 15 * 第三步:设置prefix属性,指定需要注入属性的前缀; 16 * 第四步:添加数据校验注解,开启数据校验; 17 * 18 * 注意点: 19 * 一、nickName和createdDate在yml配置文件中,对应参数分别是中划线和下划线,用于测试其对属性名匹配的松散性 20 * 二、email和iphone 测试其支持JSR303数据校验 21 * 三、abilities 测试其支持复杂的数据结构 22 * 23 * 若想运行成功,需要注释33行 24 */ 25 26 @Component 27 @ConfigurationProperties(prefix = "itdragon") 28 @Validated 29 public class ConfigurationPropertiesEntity { 30 31 private String nickName; // 解析成功,支持松散匹配属性 32 private String email; 33 // @Email // 解析失败,数据校验成功:BindValidationException: Binding validation errors on itdragon 34 private String iphone; 35 private List<String> abilities; 36 private Date createdDate; // 解析成功,支持松散匹配属性 37 38 // @ConfigurationProperties("#{(1+2-3)/4*5}") 39 private String operator; // 语法报错,不支持SpEL表达式:not applicable to field 40 41 public String getNickName() { 42 return nickName; 43 } 44 45 public void setNickName(String nickName) { 46 this.nickName = nickName; 47 } 48 49 public String getEmail() { 50 return email; 51 } 52 53 public void setEmail(String email) { 54 this.email = email; 55 } 56 57 public String getIphone() { 58 return iphone; 59 } 60 61 public void setIphone(String iphone) { 62 this.iphone = iphone; 63 } 64 65 public List<String> getAbilities() { 66 return abilities; 67 } 68 69 public void setAbilities(List<String> abilities) { 70 this.abilities = abilities; 71 } 72 73 public Date getCreatedDate() { 74 return createdDate; 75 } 76 77 public void setCreatedDate(Date createdDate) { 78 this.createdDate = createdDate; 79 } 80 81 @Override 82 public String toString() { 83 return "ConfigurationPropertiesEntity{" + 84 "nickName=‘" + nickName + ‘‘‘ + 85 ", email=‘" + email + ‘‘‘ + 86 ", iphone=‘" + iphone + ‘‘‘ + 87 ", abilities=" + abilities + 88 ", createdDate=" + createdDate + 89 ‘}‘; 90 } 91 }
三)@Value详解
第一步:在属性上添加Value注解,通过${}设置参数从配置文件中注入值;
第二步:修改${itdragon.ceatred_date}
中的参数值,改为${itdragon.ceatredDate}
测试是否能解析成功;
第三步:添加数据校验Validated注解,开启数据校验,测试其是否支持数据校验的功能;
第四步:测试Value注解是否支持SpEL表达式;
1 package com.itdragon.entity; 2 3 import org.springframework.beans.factory.annotation.Value; 4 import org.springframework.stereotype.Component; 5 import org.springframework.validation.annotation.Validated; 6 7 import javax.validation.constraints.Email; 8 import java.util.Date; 9 import java.util.List; 10 11 /** 12 * Value 注解语法类 13 * 第一步:在属性上添加注解Value注入参数 14 * 第二步:把Value注解修饰的类添加到Spring的IOC容器中; 15 * 第三步:添加数据校验注解,检查是否支持数据校验; 16 * 17 * 注意点: 18 * 一、nickName和createdDate在yml配置文件中,对应参数分别是中划线和下划线,用于测试其对属性名匹配的松散性 19 * 二、email和iphone 测试其支持JSR303数据校验 20 * 三、abilities 测试其支持复杂的数据结构 21 * 22 * 结论: 23 * 一、createDate取值必须和yml配置文件中的参数保持一致, 24 * 二、既是在iphone上添加邮箱验证注解依然可以通过测试, 25 * 三、不支持复杂的数据结构,提示错误和第一条相同:IllegalArgumentException: Could not resolve placeholder ‘itdragon.abilities‘ in value "${itdragon.abilities}" 26 * 27 * 若想运行成功,需要注释42行;修改44行,将ceatredDate修改为ceatred_date 28 */ 29 30 @Component 31 @Validated 32 public class ValueEntity { 33 34 @Value("${itdragon.nick-name}") 35 private String nickName; 36 @Value("${itdragon.email}") 37 private String email; 38 @Email 39 @Value("${itdragon.iphone}") // 解析成功,并不支持数据校验 40 private String iphone; 41 // @Value("${itdragon.abilities}") // 解析错误,并不支持复杂的数据结构 42 private List<String> abilities; 43 // @Value("${itdragon.ceatredDate}") // 解析错误,并不支持松散匹配属性,必须严格一致 44 private Date createdDate; 45 46 // Value注解的强大一面:支持SpEL表达式 47 @Value("#{(1+2-3)/4*5}") // 算术运算 48 private String operator; 49 @Value("#{1>2 || 2 <= 3}") // 关系运算 50 private Boolean comparison; 51 @Value("#{systemProperties[‘java.version‘]}") // 系统配置:os.name 52 private String systemProperties; 53 @Value("#{T(java.lang.Math).abs(-18)}") // 表达式 54 private String mapExpression; 55 56 public String getNickName() { 57 return nickName; 58 } 59 60 public void setNickName(String nickName) { 61 this.nickName = nickName; 62 } 63 64 public String getEmail() { 65 return email; 66 } 67 68 public void setEmail(String email) { 69 this.email = email; 70 } 71 72 public String getIphone() { 73 return iphone; 74 } 75 76 public void setIphone(String iphone) { 77 this.iphone = iphone; 78 } 79 80 public List<String> getAbilities() { 81 return abilities; 82 } 83 84 public void setAbilities(List<String> abilities) { 85 this.abilities = abilities; 86 } 87 88 public Date getCreatedDate() { 89 return createdDate; 90 } 91 92 public void setCreatedDate(Date createdDate) { 93 this.createdDate = createdDate; 94 } 95 96 public String getOperator() { 97 return operator; 98 } 99 100 public void setOperator(String operator) { 101 this.operator = operator; 102 } 103 104 public Boolean getComparison() { 105 return comparison; 106 } 107 108 public void setComparison(Boolean comparison) { 109 this.comparison = comparison; 110 } 111 112 public String getSystemProperties() { 113 return systemProperties; 114 } 115 116 public void setSystemProperties(String systemProperties) { 117 this.systemProperties = systemProperties; 118 } 119 120 public String getMapExpression() { 121 return mapExpression; 122 } 123 124 public void setMapExpression(String mapExpression) { 125 this.mapExpression = mapExpression; 126 } 127 128 @Override 129 public String toString() { 130 return "ValueEntity{" + 131 "nickName=‘" + nickName + ‘‘‘ + 132 ", email=‘" + email + ‘‘‘ + 133 ", iphone=‘" + iphone + ‘‘‘ + 134 ", abilities=" + abilities + 135 ", createdDate=" + createdDate + 136 ", operator=‘" + operator + ‘‘‘ + 137 ", comparison=" + comparison + 138 ", systemProperties=‘" + systemProperties + ‘‘‘ + 139 ", mapExpression=‘" + mapExpression + ‘‘‘ + 140 ‘}‘; 141 } 142 }
四)配置文件取值小结
一、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为完整路径}
1 package com.itdragon.entity; 2 3 import org.springframework.boot.context.properties.ConfigurationProperties; 4 import org.springframework.stereotype.Component; 5 6 /** 7 * 随机数和占位符语法类 8 */ 9 10 @Component 11 @ConfigurationProperties(prefix = "ran") 12 public class RandomEntity { 13 14 private String ranValue; // 随机生成一个字符串 15 private Integer ranInt; // 随机生成一个整数 16 private Long ranLong; // 随机生成一个长整数 17 private Integer ranIntNum; // 在指定范围内随机生成一个整数 18 private Integer ranIntRange;// 在指定区间内随机生成一个整数 19 private String ranPlaceholder;// 占位符 20 21 public String getRanValue() { 22 return ranValue; 23 } 24 25 public void setRanValue(String ranValue) { 26 this.ranValue = ranValue; 27 } 28 29 public Integer getRanInt() { 30 return ranInt; 31 } 32 33 public void setRanInt(Integer ranInt) { 34 this.ranInt = ranInt; 35 } 36 37 public Long getRanLong() { 38 return ranLong; 39 } 40 41 public void setRanLong(Long ranLong) { 42 this.ranLong = ranLong; 43 } 44 45 public Integer getRanIntNum() { 46 return ranIntNum; 47 } 48 49 public void setRanIntNum(Integer ranIntNum) { 50 this.ranIntNum = ranIntNum; 51 } 52 53 public Integer getRanIntRange() { 54 return ranIntRange; 55 } 56 57 public void setRanIntRange(Integer ranIntRange) { 58 this.ranIntRange = ranIntRange; 59 } 60 61 public String getRanPlaceholder() { 62 return ranPlaceholder; 63 } 64 65 public void setRanPlaceholder(String ranPlaceholder) { 66 this.ranPlaceholder = ranPlaceholder; 67 } 68 69 @Override 70 public String toString() { 71 return "RandomEntity{" + 72 "ranValue=‘" + ranValue + ‘‘‘ + 73 ", ranInt=" + ranInt + 74 ", ranLong=" + ranLong + 75 ", ranIntNum=" + ranIntNum + 76 ", ranIntRange=" + ranIntRange + 77 ", ranPlaceholder=‘" + ranPlaceholder + ‘‘‘ + 78 ‘}‘; 79 } 80 }
测试代码:
1 package com.itdragon.yml; 2 3 import com.itdragon.entity.*; 4 import org.junit.Test; 5 import org.junit.runner.RunWith; 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.boot.test.context.SpringBootTest; 8 import org.springframework.test.context.junit4.SpringRunner; 9 10 @RunWith(SpringRunner.class) 11 @SpringBootTest 12 public class SpringBootYmlApplicationTests { 13 14 @Autowired 15 private UserInfo userInfo; 16 17 @Autowired 18 private YamlEntity yamlEntity; 19 20 @Autowired 21 private ConfigurationPropertiesEntity configurationPropertiesEntity; 22 23 @Autowired 24 private ValueEntity valueEntity; 25 26 @Autowired 27 private RandomEntity randomEntity; 28 29 @Test 30 public void contextLoads() { 31 System.out.println("YAML Grammar : " + yamlEntity); 32 // System.out.println("UserInfo : " + userInfo); 33 // System.out.println("ConfigurationProperties Grammar : " + configurationPropertiesEntity); 34 // System.out.println("Value Grammar : " + valueEntity); 35 // System.out.println("Random Grammar : " + randomEntity); 36 } 37 38 }
原文链接:https://www.cnblogs.com/itdragon/p/8686554.html
以上是关于Spring Boot配置文件详解的主要内容,如果未能解决你的问题,请参考以下文章