一、@Value获取值和@ConfigurationProperties获取值比较
如果某个业务逻辑中只需要获取配置文件中的某项值时使用@Value;
如果专门编写了一个javaBean和配置文件进行映射,使用@ConfigurationProperties
@ConfigurationProperties | @Value | |
功能 | 批量注入配置文件中的属性 | 一个一个指定 |
优先级(高优先级覆盖低优先级,配置互补) | 高 | 低 |
松散绑定(松散语法:person.lastName == person.last-name) | 支持 | 不支持 |
JSR303数据校验(@Validated) | 支持 | 不支持 |
复杂类型封装(对象、List、Set、Map,等) | 支持 | 不支持 |
配置文件格式.yml和.properties | 支持 | 支持 |
二、配置文件.properties和.yml优先级
在application.properties中添加person属性值,当application.properties和application.yml中同时定义person属性值时,同一目录下.properties配置文件的优先级高于.yml配置文件,高优先级会覆盖低优先级的属性值,并且配置互补。
person.last-name=李四
person.age=20
person.boss=false
person.birth=201901/01/02
person.maps.k1=v1
person.maps.k2=v2
person.maps.k3=v3
person.lists=a,b,c
person.dog.name=小花狗
person.dog.age=3
三、编码问题
使用.properties配置文件中的属性值时,打印在控制台的结果中文乱码。
解决方法:打开Settings,File > Settings
修改后application.properties配置文件中的中文会乱码,重新输入再次测试。
三、@Value
@Value的赋值方式和Spring IOC中使用set注入方式相同(什么是set注入) 使用set注入,值可以是:字面量、${key} 从环境变量或者配置中获取值、#{SpEL} EL表达式
<bean class="cn.springboottest.springboot.bean.Person" >
<property key="lastName" value="字面量/${key}从环境变量,配置文件中获取值/#{SpEL}"></property>
</bean>
测试,先将@ConfigurationProperties(prefix = “person”)注释掉
package cn.springboottest.springboot.bean;
import org.springframework.beans.factory.annotation.Value;
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: 告诉Spring Boot将本类中的所有属性和配置文件中相关的配置进行绑定
* prefix ="person":配置文件中哪个下面的所有属性进行一一映射
*
* 只有这个组件是容器中的组件,才能使用容器提供的@ConfigurationProperties功能
*
* @ConfigurationProperties(prefix = "person")默认从全局配置文件中获取值;
*
*
*/
@Component
//@ConfigurationProperties(prefix = "person")
public class Person {
/*
<bean class="cn.springboottest.springboot.bean.Person" >
<property key="lastName" value="字面量/${key}从环境变量,配置文件中获取值/#{SpEL}"></property>
</bean>
*/
@Value("${person.last-name}")
private String lastName;
@Value("#{11*5}")
private Integer age;
@Value("true")
private Boolean boss;
private Date birth;
private Map<String, Object> maps;
private List<Object> lists;
private Dog dog;
@Override
public String toString() {
return "Person{" +
"lastName='" + lastName + '\'' +
", age=" + age +
", boss=" + boss +
", birth=" + birth +
", maps=" + maps +
", lists=" + lists +
", dog=" + dog +
'}';
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Boolean getBoss() {
return boss;
}
public void setBoss(Boolean boss) {
this.boss = boss;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public Map<String, Object> getMaps() {
return maps;
}
public void setMaps(Map<String, Object> maps) {
this.maps = maps;
}
public List<Object> getLists() {
return lists;
}
public void setLists(List<Object> lists) {
this.lists = lists;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
}
测试结果:未赋值的的属性值为null
Person{lastName='李四', age=55, boss=true, birth=null, maps=null, lists=null, dog=null}
放开@ConfigurationProperties(prefix=“person”)注解配置,@Value和@ConfigurationProperties同时存在,@ConfigurationProperties优先级高于@Value,高优先级覆盖低优先级,互补配置。
四、@Value使用案例
- 创建Controller
package cn.springboottest.springboot.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@Value("${person.last-name}")
private String name;
@RequestMapping("/sayHello")
public String sayHello(){
return "Hello "+ name;
}
}
- 测试结果
五、@Validated
配置文件注入值数据校验,在类上增加注解配置@Validated
在属性值上增加@Email,代表该属性值必须是email格式,否则在编译启动的过程中会抛错。
@Value 对 @Validated + @Email 不生效
示例:
package cn.springboottest.springboot.bean;
import org.springframework.beans.factory.annotation.Value;
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;
import java.util.Map;
/**
* 将配置文件中配置的每一个属性值,映射到这个组件中
* @ConfigurationProperties: 告诉Spring Boot将本类中的所有属性和配置文件中相关的配置进行绑定
* prefix ="person":配置文件中哪个下面的所有属性进行一一映射
*
* 只有这个组件是容器中的组件,才能使用容器提供的@ConfigurationProperties功能
*
* @ConfigurationProperties(prefix = "person")默认从全局配置文件中获取值;
*
*
*/
@Component
@ConfigurationProperties(prefix = "person")
@Validated
public class Person {
/*
<bean class="cn.springboottest.springboot.bean.Person" >
<property key="lastName" value="字面量/${key}从环境变量,配置文件中获取值/#{SpEL}"></property>
</bean>
*/
//@Value("${person.last-name}")
@Email
private String lastName;
//@Value("#{11*5}")
private Integer age;
//@Value("true")
private Boolean boss;
private Date birth;
private Map<String, Object> maps;
private List<Object> lists;
private Dog dog;
@Override
public String toString() {
return "Person{" +
"lastName='" + lastName + '\'' +
", age=" + age +
", boss=" + boss +
", birth=" + birth +
", maps=" + maps +
", lists=" + lists +
", dog=" + dog +
'}';
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Boolean getBoss() {
return boss;
}
public void setBoss(Boolean boss) {
this.boss = boss;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public Map<String, Object> getMaps() {
return maps;
}
public void setMaps(Map<String, Object> maps) {
this.maps = maps;
}
public List<Object> getLists() {
return lists;
}
public void setLists(List<Object> lists) {
this.lists = lists;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
}
测试结果:
Caused by: org.springframework.boot.context.properties.bind.validation.BindValidationException: Binding validation errors on person
- Field error in object 'person' on field 'lastName': rejected value [李四]; codes [Email.person.lastName,Email.lastName,Email.java.lang.String,Email]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [person.lastName,lastName]; arguments []; default message [lastName],[Ljavax.validation.constraints.Pattern$Flag;@1d572e62,.*]; default message [不是一个合法的电子邮件地址]; origin class path resource [application.properties]:1:18
at org.springframework.boot.context.properties.bind.validation.ValidationBindHandler.getBindValidationException(ValidationBindHandler.java:121)
at org.springframework.boot.context.properties.bind.validation.ValidationBindHandler.validateAndPush(ValidationBindHandler.java:112)
at org.springframework.boot.context.properties.bind.validation.ValidationBindHandler.validate(ValidationBindHandler.java:90)
at org.springframework.boot.context.properties.bind.validation.ValidationBindHandler.onFinish(ValidationBindHandler.java:82)
at org.springframework.boot.context.properties.bind.Binder.handleBindResult(Binder.java:228)
at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:215)
... 46 more