目录
2 @ConfigurationProperties和@value的区别
在平时开发中,我们会将大量的参数配置在application.properties或者application.yml文件中,通过@ConfigurationProperties注解或者@value注解可以很方便的拿到这些值。
两种注解斗能够读取配置文件中属性并绑定到javaBean中,但两种存在以下不同
1)使用位置不同
@ConfigurationProperties:标注在JavaBean的类名上;
@Value:标注在JavaBean的属性上。
2)功能
@ConfigurationProperties:用于批量绑定配置文件中的配置;
@Value:只能一个一个的指定需要绑定的位置,绑定粒度更小
3)松散绑定支持不同
@ConfigurationProperties:支持松散绑定,例如实体类Person中有一个属性为username,那么配置文件中的属性名支持以下写法:person.username、person_name、person.user_name、PERSON_USER_NAME
@Value:不支持松散绑定
4) 复杂类型封装
@ConfigurationProperties:支持所有类型的封装,例如Map、List、Set以及对象等
@Value:只支持基本数据类型的封装,例如:字符串、布尔值、整数等类型
5)应用场景不同,两者并没有明显的优劣势之分,它们只适合应用的场景不同。若只是获取配置文件中的某项值,则推荐使用@Value注解;若专门编写了一个JavaBean来和配置文件进行映射,则建议使用@ConfigurationProperties注解。
实体类:
- package com.liubujun.springdataelasticsearch.entity;
-
- import org.springframework.boot.context.properties.ConfigurationProperties;
- import org.springframework.stereotype.Component;
-
- /**
- * @Author: liubujun
- * @Date: 2022/6/30 13:57
- */
-
- @Component
- @ConfigurationProperties(prefix = "person")
- public class Person {
-
- private String username;
-
- private Integer age;
-
- private String address;
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public Integer getAge() {
- return age;
- }
-
- public void setAge(Integer age) {
- this.age = age;
- }
-
- public String getAddress() {
- return address;
- }
-
- public void setAddress(String address) {
- this.address = address;
- }
-
- @Override
- public String toString() {
- return "Person{" +
- "username='" + username + '\'' +
- ", age=" + age +
- ", address='" + address + '\'' +
- '}';
- }
-
- }
配置文件:
- person.username=Tony老师
- person.age=21
- person.address=地球村
测试类:
- @Autowired
- private Person person;
-
- @Test
- public void test(){
- System.out.println("姓名:"+person.getUsername()+"、年龄:"+person.getAge()+"、地址:"+person.getAddress());
- }
运行结果:
从运行结果中可发现我们能够成功的从配置文件中获取相关值。
注意:@ConfigurationProperties支持松散绑定
配置文件改成:
- person.user_name=Tony老师
- person.age=21
- person.address=地球村
测试发现依然正常获取到值:
注意: @ConfigurationProperties支持复杂类型封装
配置文件改成:
- person.user_name=Tony老师
- person.age=21
- person.address=地球村
- person.email[0]=tony0@qq.com
- person.email[1]=tony1@qq.com
- person.email[2]=tony2@qq.com
实体类加个字段对应修改:
- @Component
- @ConfigurationProperties(value = "person")
- public class Person {
-
-
- private String username;
-
-
- private Integer age;
-
-
- private String address;
-
- private List<String> email;
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public Integer getAge() {
- return age;
- }
-
- public void setAge(Integer age) {
- this.age = age;
- }
-
- public String getAddress() {
- return address;
- }
-
- public void setAddress(String address) {
- this.address = address;
- }
-
- public List<String> getEmail() {
- return email;
- }
-
- public void setEmail(List<String> email) {
- this.email = email;
- }
-
- @Override
- public String toString() {
- return "Person{" +
- "username='" + username + '\'' +
- ", age=" + age +
- ", address='" + address + '\'' +
- ", email=" + email +
- '}';
- }
- }
测试类:
- @Autowired
- private Person person;
-
-
- @Test
- public void test(){
- System.out.println("姓名:"+person.getUsername()+"、年龄:"+person.getAge()+"、地址:"+person.getAddress()+"、email:"+person.getEmail());
- }
结果:
实体类如下:其它配置不变
- @Component
- public class Person {
-
- @Value("${person_username}")
- private String username;
-
- @Value("${person.age}")
- private Integer age;
-
- @Value("${person.address}")
- private String address;
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public Integer getAge() {
- return age;
- }
-
- public void setAge(Integer age) {
- this.age = age;
- }
-
- public String getAddress() {
- return address;
- }
-
- public void setAddress(String address) {
- this.address = address;
- }
-
- @Override
- public String toString() {
- return "Person{" +
- "username='" + username + '\'' +
- ", age=" + age +
- ", address='" + address + '\'' +
- '}';
- }
-
- }
测试正常输出:
注意:@Value不能够支持松散绑定,如果将配置文件改成如下:
- person.user_name=Tony老师
- person.age=21
- person.address=地球村
测试发现获取不到“username”的值,报错信息如下:
Error creating bean with name 'person': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'person_username' in value "${person_username}"
注意:@Value不支持复杂类型封装,将实体类增加一个List类型的字段
- @Component
- public class Person {
-
- @Value("${person.username}")
- private String username;
-
- @Value("${person.age}")
- private Integer age;
-
- @Value("${person.address}")
- private String address;
-
- @Value("${person.email}")
- private List<String> email;
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public Integer getAge() {
- return age;
- }
-
- public void setAge(Integer age) {
- this.age = age;
- }
-
- public String getAddress() {
- return address;
- }
-
- public void setAddress(String address) {
- this.address = address;
- }
-
- public List<String> getEmail() {
- return email;
- }
-
- public void setEmail(List<String> email) {
- this.email = email;
- }
-
- @Override
- public String toString() {
- return "Person{" +
- "username='" + username + '\'' +
- ", age=" + age +
- ", address='" + address + '\'' +
- ", email=" + email +
- '}';
- }
- }
配置文件修改如下:
- person.user_name=Tony老师
- person.age=21
- person.address=地球村
- person.email[0]=tony0@qq.com
- person.email[1]=tony1@qq.com
- person.email[2]=tony2@qq.com
测试类:
- @Autowired
- private Person person;
-
- @Test
- public void test(){
- System.out.println("姓名:"+person.getUsername()+"、年龄:"+person.getAge()+"、地址:"+person.getAddress()+"、email:"+person.getEmail());
- }
运行之后发现报错:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'person': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'person.email' in value "${person.email}"
但是要是获取其中一个值就不会有问题:
运行结果:
在实际开发中,有大量内容需要配置管理,不可能将所有的信息放到同一个配置文件中,这样既不安全也不方便维护,我们可以将SpringBoot无关的配置单独放入其他的配置文件,在需要这些JavaBean上使用即可,SpringBoot提供了@PropertySource注解。
新建一个文件:
将之前application.properties文件内容粘贴放入该文件中。
实体类加上对应路径:
测试后发现依然可以正常获取到值