@Value与@ConfigurationProperties注解的讲解与区别

@Value和@ConfigurationProperties:

@Value注解与@ConfigurationProperties都是对对象属性进行注入配置的注解。

@Value注解:
//源码:
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Value {
    String value();
}

  1. @Value注解是spring框架的注解,用于对对象属性的注入。
  2. @Value注解只有一个value属性,值可以是字面量,#{SPEL}表达式,配置文件的${key}值等。
  3. 能作用在方法(一般是setter方法)、属性、参数、注解上。但是一般会在方法或者属性上使用该注解。
    使用方法:
@ToString
@Component
public class Student {

    //字面量,作用在成员变量里面
    @Value(value = "张三")
    private String name;
    //SPEL表达式
    @Value(value = "#{5+6}")
    private int age;
    //引用外部配置文件的属性值
    @Value("${student.sex}")
    private boolean sex;

    private String fatherName;

    private String motherName;

    private String teacherName;

    //作用在setter方法上
    @Value(value = "李四")
    public void setFatherName(String fatherName){
        this.fatherName = fatherName;
    }

    //理论上@Value注解应该使用在setter方法上,例如上面的setFatherName,但是也可以作用在下面方法,把motherName和teacherName属性也复制成value的值
    @Value(value = "王五")
    public void setMAndT(String motherName,String teacherName){
        this.motherName = motherName;
        this.teacherName = teacherName;
    }

    
}

配置文件配置:

student: 
	sex: true

测试类:

@SpringBootTest
class SpringbootstudyApplicationTests {

	
	@Autowired
	private Student student;

	@Test
	void test1() {
		System.out.println(student);
	}

}

//执行结果:
//Student(name=张三, age=11, sex=true, fatherName=李四, motherName=王五, teacherName=王五)

@ConfigurationProperties注解:
//源码
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ConfigurationProperties {

	
    @AliasFor("prefix")
    String value() default "";

    @AliasFor("value")
    String prefix() default "";

    boolean ignoreInvalidFields() default false;

    boolean ignoreUnknownFields() default true;
}
  1. @ConfigurationProperties注解是spring boot的注解,用于配置文件对对象属性的配置。
  2. 不支持字面量,也不支持SPEL表达式。
  3. 从上面源码可知,该注解能作用在类和方法上。
  4. 有四个属性:
    a)prefix:配置文件key的前缀,给属性进行值的注入时会加上此前缀,例如设为teacher,然后属性值为name,name就会把配置文件中的key为teacher.name的值进行注入。
    b)value:与prefix一样的作用。与prefix不能同时设置,除非设置的值一样。
    c)ignoreInvalidFields:是否忽略无效的字段,默认不忽略。
    d)ignoreUnknownFields:是否忽略未知字段,默认忽略。

prefix与value的值不能有大写字母,不能下划线,可以中划线,不然会非法字符报错。

ignoreInvalidFields演示:

@Setter
@ToString
@Component
@ConfigurationProperties(prefix = "pet")
public class Pet {
    private String name;
    private boolean sex;
}
pet:
  name: 旺财
  sex:master: 张三

测试代码:

@SpringBootTest
class SpringbootstudyApplicationTests {
	@Autowired
	private Pet pet;
	@Test
	void test() {
		System.out.println(pet);
	}
}

结果:
在这里插入图片描述
分析:因为ignoreInvalidFields是是否忽略无效字段,默认false不忽略,所以,Pet类中的sex属性是布尔类型,而配置文件中的该字段是字符串String类型,所以会抛出异常。

也可以设置为true,忽略无效字段:
结果为:
在这里插入图片描述
分析:sex字段因为无效被忽略了,使用默认值。

ignoreUnknownFields字段演示:

@Setter
@ToString
@Component
@ConfigurationProperties(prefix = "pet",ignoreUnknownFields = false)
public class Pet {
    private String name;
    private boolean sex;
}
pet:
  name: 旺财
  sex: true
  master: 张三

测试代码:

@SpringBootTest
class SpringbootstudyApplicationTests {
	@Autowired
	private Pet pet;
	@Test
	void test() {
		System.out.println(pet);
	}
}

结果:

Caused by: org.springframework.boot.context.properties.bind.UnboundConfigurationPropertiesException: The elements [pet.master] were left unbound.

//意思是配置文件中的pet.master在类用没有属性跟他绑定报错

分析:
ignoreUnknownFields的意思是是否忽略未知字段,默认是,所以默认情况下是不会报错,但是我设置为false之后,由于配置文件中有pet.master属性,但是类没有该属性,然后配置为不忽略未知字段,所以报错。

@ConfigurationProperties注解还支持JSR303数据校验:

@Setter
@ToString
@Component
@ConfigurationProperties(prefix = "pet")
@Validated
public class Pet {
    @Email //对name进行邮箱校验
    private String name;
    private boolean sex;
}

pet:
  name: 旺财
  sex: true
@SpringBootTest
class SpringbootstudyApplicationTests {
	@Autowired
	private Pet pet;
	@Test
	void test() {
		System.out.println(pet);
	}
}

结果:

Field error in object 'pet' on field 'name': rejected value [旺财]; codes [Email.pet.name,Email.name,Email.java.lang.String,Email]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [pet.name,name]; arguments []; default message [name],[Ljavax.validation.constraints.Pattern$Flag;@48bfb884,.*]; default message [不是一个合法的电子邮件地址]; origin class path resource [application.yml]:6:9

//因为pet.name不是邮箱格式,所以数据校验生效报错了。

支持松散绑定:
属性名匹配:

  1. teacher.schoolName.
  2. teacher.school_name
  3. teacher.school-name
  4. TEACHER.SCHOOLNAME 等等
    大小写不敏感,如果大小写不敏感之后有多个相同的属性,则只对第一个进行注入。以上可以互相配置使用。

例子:

@Component
@Data
@ConfigurationProperties(prefix = "person.configuration")
public class Person {


    private String firstName;
    private String last_name;
    private String BORN_LOCATION;
}
PERSON:
  configuRation:
    first-name: 乔丹
    LASTNAME: 迈克尔
    born_locAtion: 纽约

测试代码:

@SpringBootTest
class SpringbootstudyApplicationTests {
	@Autowired
	Person person;
	@Test
	void test() {
		System.out.println(person);
	}

}

//结果:
//Person(firstName=乔丹, last_name=迈克尔, BORN_LOCATION=纽约)  都能注入
区别总结:
比较项@Value@ConfigurationProperties
使用方式能够批量地注入配置文件中的属性需要一个个指定
所属框架SpringSpring Boot
SPEL支持不支持
JSR303数据校验不支持支持
松散绑定不支持支持
复杂类型绑定不支持支持

关于@ConfigurationProperties的复杂类型的绑定的例子可以看博主的另一篇文章:
Spring Boot application.yml文件语法

使用场景:

  1. 如果要对对象尤其是复杂对象进行配置的话推荐使用@ConfigurationProperties。
  2. 如果要对注入数据进行校验的话推荐使用@ConfigurationProperties。
  3. 如果我们只是在某个业务逻辑中需要用到配置文件的某一个值,推荐使用@Value。
  4. 如果需要用到SPEL表达式的话推荐使用@Value。
  5. 如果是spring的项目那就只能是@Value。
  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值