1.使用@ConfigurationProperties注解给JavaBean赋值
我们可以将 xxx.yml
配置文件中的值与 JavaBean 组件绑定,并且将配置文件中的值注入到 JavaBean 中
需要导入文件处理器的依赖
<!-- 导入配置文件处理器, 将JavaBean与配置文件进行绑定时会有提示 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
准备一个 yml 配置文件
# application.yml
person:
lastName: luwenhe
age: 18
boss: false
birth: 2019/1/5
maps: {k1: v1, k2: v2}
lists:
- lisi
- zhaoliu
- dd
dog:
name: xiaogou
age: 2
JavaBean 组件
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
private String lastName;
private Integer age;
private Boolean boss;
private Date birth;
private Map<String, Object> maps;
private List<Object> lists;
private Dog dog;
// 省略 getter/setter 方法
...
}
这里需要在 JavaBean 添加 @ConfigurationProperties
注解,将 JavaBean 中的属性与 yml 配置文件中配置的值进行绑定
其中 prefix = "person"
表示该 JavaBean 与 yml 配置文件中开头的 people 前缀后的属性进行映射,别忘了为 JavaBean 添加组件的注解 @Component
在 Spring Boot 的测试类中进行测试,输出对象
@RunWith(SpringRunner.class)
@SpringBootTest
public class Springboot02ConfigApplicationTests {
@Autowired
Person person;
@Test
public void contextLoads() {
System.out.println(person);
}
}
输出为:
Person{lastName='luwenhe', age=18, boss=false, birth=Sat Jan 05 00:00:00 CST 2019, maps={k1=v1, k2=v2}, lists=[lisi, zhaoliu, dd], dog=Dog{name='xiaogou', age=2}}
如果使用类似 xxx.properties
的配置文件,那么 prefix = "person"
对应的在配置文件中的设置如下:
person.last-name=张三
person.age=100
person.birth=2019/2/3
person.boss=false
person.maps.password=lwh123
person.maps.address=xxx
person.lists=a,b,c,d,e
person.dog.name=dog
person.dog.age=19
这里的 people 前缀表示配置文件中键值
如果既存在 xxx.yml 和 application.properties 两种配置文件,那么会使用后者配置文件中的信息
2. 使用@Value注解给JavaBean赋值
我们可以使用给属性添加 @Value
注解的方式将配置文件的值动态注入到 JavaBean 中,配置文件为 application.properties
在使用 @Value 注解时,value 中的值分为三种样式,分别是:字面量、配置文件中的键、Spel
下面是配置文件的配置的属性
car.name=happy
car.length=100
car.height=200
在 JavaBean 中的使用
@Component
public class Car {
@Value("${car.name}") // 注入配置文件中键是 car.name 对应的值
private String name;
@Value("${car.length}") // 注入配置文件中键是 car.lenght 对应的值
private Integer length;
@Value("${car.weight}") // 注入配置文件中键是 car.weight 对应的值
private Integer weight;
@Override
public String toString() {
return "Car{" +
"ame='" + name + '\'' +
", length=" + length +
", weight=" + weight +
'}';
}
}
测试文件:
@RunWith(SpringRunner.class)
@SpringBootTest
public class Springboot02ConfigApplicationTests {
@Autowired
private Car car;
@Test
public void test1() {
System.out.println(car);
}
}
结果是:
Car{ame='happy', length=100, weight=200}
3. @Value和@ConfigurationProperties的比较
①. 松散绑定
对于 @ConfigurationProperties
,如果 Bean 中的属性名是 lastName,那么配置文件中的命名可以是以下三种:
- 标准格式:
person.lastName
- 大写用 -:
person.last-name
- 小写用 _:
person.last_name
对于 @Value
,如果 Bean 中的属性名是 lastName,那么配置文件中的命名只能是类似 person.lastName
这种标准的形式
②. SpEL语法
对于 @ConfigurationProperties
,不能直接在配置文件中使用类似 person.age=#{10*23}
这也的表达式
对于 @Value
,则可以直接在属性名上面加上类似 @Value("#{10*12}")
这样的表达式
③. JSR303数据校验
对于 @ConfigurationProperties
,支持使用数据校验
@Component
@ConfigurationProperties(prefix = "person")
@Validated //需要加上数据校验的注解
public class Person {
@Email //对 lastName 属性进行邮箱格式的校验
private String lastName;
...
}
对于 @Value
,则不支持使用数据校验
④. 复杂数据格式封装
如果数据格式是类似 Map 或 List 这种比较复杂的格式
对于 @ConfigurationProperties
,他是支持的,即直接从配置文件中获取,这个在上面也演示过了
对于 @Value
,它是不支持的,如果配置文件是这样的
car.maps.price1=1
car.maps.price2=11
car.maps.price3=111
在 Bean 中使用如下的注解
@Component
public class Car {
@Value("${car.maps}")
private Map<String, Integer> map;
}
在测试的时候会报出 Could not resolve placeholder 'car.maps' in value "${car.maps}"
这样的错误
⑤. 对比
@ConfigurationProperties | @Value | |
---|---|---|
功能 | 批量注入配置文件中的属性 | 需要一个个的指定 |
松散绑定(语法) | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复杂数据格式封装 | 支持 | 不支持 |
两者都可以使用 xxx.yml
或者 xxx.properties
来获取值
⑥. 两者的使用场景
我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,如在展示层直接获取配置文件中的值,则可以使用 @Value
;
如果我们专门编写了一个 JavaBean 来和配置文件进行映射并且获取值,则可以使用@ConfigurationProperties
;