• @ConfigurationProperties和@Value的区别


    目录

    1 前言

    2 @ConfigurationProperties和@value的区别

    3 用法

    3.1 @ConfigurationProperties

    3.2 @Value

     4 指定配置文件


    1 前言

    在平时开发中,我们会将大量的参数配置在application.properties或者application.yml文件中,通过@ConfigurationProperties注解或者@value注解可以很方便的拿到这些值。

    2 @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注解。

    3 用法

    3.1 @ConfigurationProperties

    实体类:

    1. package com.liubujun.springdataelasticsearch.entity;
    2. import org.springframework.boot.context.properties.ConfigurationProperties;
    3. import org.springframework.stereotype.Component;
    4. /**
    5. * @Author: liubujun
    6. * @Date: 2022/6/30 13:57
    7. */
    8. @Component
    9. @ConfigurationProperties(prefix = "person")
    10. public class Person {
    11. private String username;
    12. private Integer age;
    13. private String address;
    14. public String getUsername() {
    15. return username;
    16. }
    17. public void setUsername(String username) {
    18. this.username = username;
    19. }
    20. public Integer getAge() {
    21. return age;
    22. }
    23. public void setAge(Integer age) {
    24. this.age = age;
    25. }
    26. public String getAddress() {
    27. return address;
    28. }
    29. public void setAddress(String address) {
    30. this.address = address;
    31. }
    32. @Override
    33. public String toString() {
    34. return "Person{" +
    35. "username='" + username + '\'' +
    36. ", age=" + age +
    37. ", address='" + address + '\'' +
    38. '}';
    39. }
    40. }

    配置文件:

    1. person.username=Tony老师
    2. person.age=21
    3. person.address=地球村

    测试类:

    1. @Autowired
    2. private Person person;
    3. @Test
    4. public void test(){
    5. System.out.println("姓名:"+person.getUsername()+"、年龄:"+person.getAge()+"、地址:"+person.getAddress());
    6. }

    运行结果:

     从运行结果中可发现我们能够成功的从配置文件中获取相关值。

    注意:@ConfigurationProperties支持松散绑定

    配置文件改成:

    1. person.user_name=Tony老师
    2. person.age=21
    3. person.address=地球村

    测试发现依然正常获取到值:

    注意: @ConfigurationProperties支持复杂类型封装

    配置文件改成:

    1. person.user_name=Tony老师
    2. person.age=21
    3. person.address=地球村
    4. person.email[0]=tony0@qq.com
    5. person.email[1]=tony1@qq.com
    6. person.email[2]=tony2@qq.com

    实体类加个字段对应修改:

    1. @Component
    2. @ConfigurationProperties(value = "person")
    3. public class Person {
    4. private String username;
    5. private Integer age;
    6. private String address;
    7. private List<String> email;
    8. public String getUsername() {
    9. return username;
    10. }
    11. public void setUsername(String username) {
    12. this.username = username;
    13. }
    14. public Integer getAge() {
    15. return age;
    16. }
    17. public void setAge(Integer age) {
    18. this.age = age;
    19. }
    20. public String getAddress() {
    21. return address;
    22. }
    23. public void setAddress(String address) {
    24. this.address = address;
    25. }
    26. public List<String> getEmail() {
    27. return email;
    28. }
    29. public void setEmail(List<String> email) {
    30. this.email = email;
    31. }
    32. @Override
    33. public String toString() {
    34. return "Person{" +
    35. "username='" + username + '\'' +
    36. ", age=" + age +
    37. ", address='" + address + '\'' +
    38. ", email=" + email +
    39. '}';
    40. }
    41. }

    测试类:

    1. @Autowired
    2. private Person person;
    3. @Test
    4. public void test(){
    5. System.out.println("姓名:"+person.getUsername()+"、年龄:"+person.getAge()+"、地址:"+person.getAddress()+"、email:"+person.getEmail());
    6. }

    结果:

    3.2 @Value

    实体类如下:其它配置不变

    1. @Component
    2. public class Person {
    3. @Value("${person_username}")
    4. private String username;
    5. @Value("${person.age}")
    6. private Integer age;
    7. @Value("${person.address}")
    8. private String address;
    9. public String getUsername() {
    10. return username;
    11. }
    12. public void setUsername(String username) {
    13. this.username = username;
    14. }
    15. public Integer getAge() {
    16. return age;
    17. }
    18. public void setAge(Integer age) {
    19. this.age = age;
    20. }
    21. public String getAddress() {
    22. return address;
    23. }
    24. public void setAddress(String address) {
    25. this.address = address;
    26. }
    27. @Override
    28. public String toString() {
    29. return "Person{" +
    30. "username='" + username + '\'' +
    31. ", age=" + age +
    32. ", address='" + address + '\'' +
    33. '}';
    34. }
    35. }

    测试正常输出:

    注意:@Value不能够支持松散绑定,如果将配置文件改成如下:

    1. person.user_name=Tony老师
    2. person.age=21
    3. 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类型的字段

    1. @Component
    2. public class Person {
    3. @Value("${person.username}")
    4. private String username;
    5. @Value("${person.age}")
    6. private Integer age;
    7. @Value("${person.address}")
    8. private String address;
    9. @Value("${person.email}")
    10. private List<String> email;
    11. public String getUsername() {
    12. return username;
    13. }
    14. public void setUsername(String username) {
    15. this.username = username;
    16. }
    17. public Integer getAge() {
    18. return age;
    19. }
    20. public void setAge(Integer age) {
    21. this.age = age;
    22. }
    23. public String getAddress() {
    24. return address;
    25. }
    26. public void setAddress(String address) {
    27. this.address = address;
    28. }
    29. public List<String> getEmail() {
    30. return email;
    31. }
    32. public void setEmail(List<String> email) {
    33. this.email = email;
    34. }
    35. @Override
    36. public String toString() {
    37. return "Person{" +
    38. "username='" + username + '\'' +
    39. ", age=" + age +
    40. ", address='" + address + '\'' +
    41. ", email=" + email +
    42. '}';
    43. }
    44. }

    配置文件修改如下:

    1. person.user_name=Tony老师
    2. person.age=21
    3. person.address=地球村
    4. person.email[0]=tony0@qq.com
    5. person.email[1]=tony1@qq.com
    6. person.email[2]=tony2@qq.com

    测试类:

    1. @Autowired
    2. private Person person;
    3. @Test
    4. public void test(){
    5. System.out.println("姓名:"+person.getUsername()+"、年龄:"+person.getAge()+"、地址:"+person.getAddress()+"、email:"+person.getEmail());
    6. }

    运行之后发现报错:

    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}"

    但是要是获取其中一个值就不会有问题:

     运行结果:

     4 指定配置文件

    在实际开发中,有大量内容需要配置管理,不可能将所有的信息放到同一个配置文件中,这样既不安全也不方便维护,我们可以将SpringBoot无关的配置单独放入其他的配置文件,在需要这些JavaBean上使用即可,SpringBoot提供了@PropertySource注解。

    新建一个文件:

    将之前application.properties文件内容粘贴放入该文件中。

    实体类加上对应路径:

     测试后发现依然可以正常获取到值

  • 相关阅读:
    “金融级”数字底座:从时代的“源启”,到“源启”的时代
    尝试用Unity还原蔚蓝(Celeste)—— 真·操控、移动、手感篇
    本人碰到的RN项目的坑
    底层驱动day4作业
    jmeter学习记录
    线上宝塔部署的springboot项目在执行elasticsearchRepository.saveAll后就挂掉的解决方法
    (附源码)springboot幼儿园管理系统 毕业设计 160901
    企业如何搭建自己的知识库?
    超宽带uwb精准定位,厘米级室内定位技术,实时高精度方案应用
    MySQL的故事——MySQL架构与历史
  • 原文地址:https://blog.csdn.net/qq_50652600/article/details/125539362