Blogger Information
Blog 41
fans 0
comment 0
visits 25310
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
5、【网摘】Spring Boot配置绑定
自由之上
Original
553 people have browsed it

前言

所谓“配置绑定”就是把配置文件中的值与 JavaBean 中对应的属性进行绑定。通常,我们会把一些配置信息(例如,数据库配置)放在配置文件中,然后通过 Java 代码去读取该配置文件,并且把配置文件中指定的配置封装到 JavaBean(实体类) 中。
SpringBoot 提供了以下 2 种方式进行配置绑定:

  1. 使用 @ConfigurationProperties 注解
  2. 使用 @Value 注解

一、@ConfigurationProperties

通过 Spring Boot 提供的 @ConfigurationProperties 注解,可以将全局配置文件中的配置数据绑定到 JavaBean 中。
下面我们以 Spring Boot 项目 helloworld 为例,演示如何通过 @ConfigurationProperties 注解进行配置绑定。

1、在 helloworld 的全局配置文件 application.yml 中添加以下自定义属性。

  1. person:
  2. lastName: 张三
  3. age: 18
  4. boss: false
  5. birth: 1990/12/12
  6. maps: { k1: v1,k2: 12 }
  7. lists:
  8. lisi
  9. zhaoliu
  10. dog:
  11. name: 迪迪
  12. age: 5

2、在 helloworld 项目的 net.biancheng.www.bean 中创建一个名为 Person 的实体类,并将配置文件中的属性映射到这个实体类上,代码如下。

  1. package net.biancheng.www.bean;
  2. import org.springframework.boot.context.properties.ConfigurationProperties;
  3. import org.springframework.stereotype.Component;
  4. import java.util.Date;
  5. import java.util.List;
  6. import java.util.Map;
  7. /**
  8. * 将配置文件中配置的每一个属性的值,映射到这个组件中
  9. *
  10. * @ConfigurationProperties:告诉 SpringBoot 将本类中的所有属性和配置文件中相关的配置进行绑定;
  11. * prefix = "person":配置文件中哪个下面的所有属性进行一一映射
  12. *
  13. * 只有这个组件是容器中的组件,才能使用容器提供的@ConfigurationProperties功能;
  14. */
  15. @Component
  16. @ConfigurationProperties(prefix = "person")
  17. public class Person {
  18. private String lastName;
  19. private Integer age;
  20. private Boolean boss;
  21. private Date birth;
  22. private Map<String, Object> maps;
  23. private List<Object> lists;
  24. private Dog dog;
  25. public Person() {
  26. }
  27. public String getLastName() {
  28. return lastName;
  29. }
  30. public void setLastName(String lastName) {
  31. this.lastName = lastName;
  32. }
  33. public Integer getAge() {
  34. return age;
  35. }
  36. public void setAge(Integer age) {
  37. this.age = age;
  38. }
  39. public Boolean getBoss() {
  40. return boss;
  41. }
  42. public void setBoss(Boolean boss) {
  43. this.boss = boss;
  44. }
  45. public Date getBirth() {
  46. return birth;
  47. }
  48. public void setBirth(Date birth) {
  49. this.birth = birth;
  50. }
  51. public Map<String, Object> getMaps() {
  52. return maps;
  53. }
  54. public void setMaps(Map<String, Object> maps) {
  55. this.maps = maps;
  56. }
  57. public List<Object> getLists() {
  58. return lists;
  59. }
  60. public void setLists(List<Object> lists) {
  61. this.lists = lists;
  62. }
  63. public Dog getDog() {
  64. return dog;
  65. }
  66. public void setDog(Dog dog) {
  67. this.dog = dog;
  68. }
  69. public Person(String lastName, Integer age, Boolean boss, Date birth, Map<String, Object> maps, List<Object> lists, Dog dog) {
  70. this.lastName = lastName;
  71. this.age = age;
  72. this.boss = boss;
  73. this.birth = birth;
  74. this.maps = maps;
  75. this.lists = lists;
  76. this.dog = dog;
  77. }
  78. @Override
  79. public String toString() {
  80. return "Person{" +
  81. "lastName='" + lastName + '\'' +
  82. ", age=" + age +
  83. ", boss=" + boss +
  84. ", birth=" + birth +
  85. ", maps=" + maps +
  86. ", lists=" + lists +
  87. ", dog=" + dog +
  88. '}';
  89. }
  90. }

注意:

  1. 只有在容器中的组件,才会拥有 SpringBoot 提供的强大功能。
  2. 如果我们想要使用 @ConfigurationProperties 注解进行配置绑定,那么首先就要保证该 JavaBean 对象在 IoC 容器中,所以需要用到 @Component 注解来添加组件到容器中。
  3. JavaBean 上使用了注解 @ConfigurationProperties(prefix = “person”) ,它表示将这个 JavaBean 中的所有属性与配置文件中以“person”为前缀的配置进行绑定。

3、在 net.biancheng.www.bean 中,创建一个名为 Dog 的 JavaBean,代码如下。

  1. package net.biancheng.www.bean;
  2. public class Dog {
  3. private String name;
  4. private String age;
  5. public Dog() {
  6. }
  7. public Dog(String name, String age) {
  8. this.name = name;
  9. this.age = age;
  10. }
  11. public void setName(String name) {
  12. this.name = name;
  13. }
  14. public void setAge(String age) {
  15. this.age = age;
  16. }
  17. public String getName() {
  18. return name;
  19. }
  20. public String getAge() {
  21. return age;
  22. }
  23. }

4、修改 HelloController 的代码,在浏览器中展示配置文件中各个属性值,代码如下。

  1. package net.biancheng.www.controller;
  2. import net.biancheng.www.bean.Person;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.web.bind.annotation.RequestMapping;
  6. import org.springframework.web.bind.annotation.ResponseBody;
  7. @Controller
  8. public class HelloController {
  9. @Autowired
  10. private Person person;
  11. @ResponseBody
  12. @RequestMapping("/hello")
  13. public Person hello() {
  14. return person;
  15. }
  16. }

5、重启项目,使用浏览器访问 “http://localhost:8081/hello”,结果如下图。

二、@Value

当我们只需要读取配置文件中的某一个配置时,可以通过 @Value 注解获取。

1、以 Spring Boot 项目 helloworld 为例,修改实体类 Person 中的代码,使用 @Value 注解进行配置绑定,代码如下。

  1. package net.biancheng.www.bean;
  2. import org.springframework.beans.factory.annotation.Value;
  3. import org.springframework.boot.context.properties.ConfigurationProperties;
  4. import org.springframework.stereotype.Component;
  5. import java.util.Date;
  6. import java.util.List;
  7. import java.util.Map;
  8. @Component
  9. public class Person {
  10. @Value("${person.lastName}")
  11. private String lastName;
  12. @Value("${person.age}")
  13. private Integer age;
  14. @Value("${person.boss}")
  15. private Boolean boss;
  16. @Value("${person.birth}")
  17. private Date birth;
  18. private Map<String, Object> maps;
  19. private List<Object> lists;
  20. private Dog dog;
  21. public Person() {
  22. }
  23. public String getLastName() {
  24. return lastName;
  25. }
  26. public void setLastName(String lastName) {
  27. this.lastName = lastName;
  28. }
  29. public Integer getAge() {
  30. return age;
  31. }
  32. public void setAge(Integer age) {
  33. this.age = age;
  34. }
  35. public Boolean getBoss() {
  36. return boss;
  37. }
  38. public void setBoss(Boolean boss) {
  39. this.boss = boss;
  40. }
  41. public Date getBirth() {
  42. return birth;
  43. }
  44. public void setBirth(Date birth) {
  45. this.birth = birth;
  46. }
  47. public Map<String, Object> getMaps() {
  48. return maps;
  49. }
  50. public void setMaps(Map<String, Object> maps) {
  51. this.maps = maps;
  52. }
  53. public List<Object> getLists() {
  54. return lists;
  55. }
  56. public void setLists(List<Object> lists) {
  57. this.lists = lists;
  58. }
  59. public Dog getDog() {
  60. return dog;
  61. }
  62. public void setDog(Dog dog) {
  63. this.dog = dog;
  64. }
  65. public Person(String lastName, Integer age, Boolean boss, Date birth, Map<String, Object> maps, List<Object> lists, Dog dog) {
  66. this.lastName = lastName;
  67. this.age = age;
  68. this.boss = boss;
  69. this.birth = birth;
  70. this.maps = maps;
  71. this.lists = lists;
  72. this.dog = dog;
  73. }
  74. @Override
  75. public String toString() {
  76. return "Person{" +
  77. "lastName='" + lastName + '\'' +
  78. ", age=" + age +
  79. ", boss=" + boss +
  80. ", birth=" + birth +
  81. ", maps=" + maps +
  82. ", lists=" + lists +
  83. ", dog=" + dog +
  84. '}';
  85. }
  86. }

2、重启项目,使用浏览器访问 “http://localhost:8081/hello”,结果如下图。

三、@Value@ConfigurationProperties 对比

@Value@ConfigurationProperties 注解都能读取配置文件中的属性值并绑定到 JavaBean 中,但两者存在以下不同。

1、使用位置不同

2、功能不同

3、松散绑定支持不同

  • @ConfigurationProperties:支持松散绑定(松散语法),例如实体类 Person 中有一个属性为 firstName,那么配置文件中的属性名支持以下写法:
  1. person.firstName
  2. person.first-name
  3. person.first_name
  4. PERSON_FIRST_NAME
  • @Vaule:不支持松散绑定。

4、SpEL 支持不同

5、复杂类型封装

  • @ConfigurationProperties:支持所有类型数据的封装,例如 Map、List、Set、以及对象等;
  • @Value:只支持基本数据类型的封装,例如字符串、布尔值、整数等类型。

6、应用场景不同

@Value@ConfigurationProperties 两个注解之间,并没有明显的优劣之分,它们只是适合的应用场景不同而已。

  • 若只是获取配置文件中的某项值,则推荐使用 @Value 注解;
  • 若专门编写了一个 JavaBean 来和配置文件进行映射,则建议使用 @ConfigurationProperties 注解。
    我们在选用时,根据实际应用场景选择合适的注解能达到事半功倍的效果。

四、@PropertySource

如果将所有的配置都集中到 application.properties 或 application.yml 中,那么这个配置文件会十分的臃肿且难以维护,因此我们通常会将与 Spring Boot 无关的配置(例如自定义配置)提取出来,写在一个单独的配置文件中,并在对应的 JavaBean 上使用 @PropertySource 注解指向该配置文件。

1、以 helloworld 为例,将与 person 相关的自定义配置移动到 src/main/resources 下的 person.properties 中(注意,必须把 application.properties 或 application.yml 中的相关配置删除),如下图。

person.properties 的配置如下。

  1. person.last-name=李四
  2. person.age=12
  3. person.birth=2000/12/15
  4. person.boss=false
  5. person.maps.k1=v1
  6. person.maps.k2=14
  7. person.lists=a,b,c
  8. person.dog.name=dog
  9. person.dog.age=2

2、在 Person 使用 @PropertySource 注解指向 person.properties,代码如下。

  1. package net.biancheng.www.bean;
  2. import org.springframework.beans.factory.annotation.Value;
  3. import org.springframework.boot.context.properties.ConfigurationProperties;
  4. import org.springframework.context.annotation.PropertySource;
  5. import org.springframework.stereotype.Component;
  6. import java.util.Date;
  7. import java.util.List;
  8. import java.util.Map;
  9. @PropertySource(value = "classpath:person.properties")//指向对应的配置文件
  10. @Component
  11. @ConfigurationProperties(prefix = "person")
  12. public class Person {
  13. private String lastName;
  14. private Integer age;
  15. private Boolean boss;
  16. private Date birth;
  17. private Map<String, Object> maps;
  18. private List<Object> lists;
  19. private Dog dog;
  20. public Person() {
  21. }
  22. public String getLastName() {
  23. return lastName;
  24. }
  25. public void setLastName(String lastName) {
  26. this.lastName = lastName;
  27. }
  28. public Integer getAge() {
  29. return age;
  30. }
  31. public void setAge(Integer age) {
  32. this.age = age;
  33. }
  34. public Boolean getBoss() {
  35. return boss;
  36. }
  37. public void setBoss(Boolean boss) {
  38. this.boss = boss;
  39. }
  40. public Date getBirth() {
  41. return birth;
  42. }
  43. public void setBirth(Date birth) {
  44. this.birth = birth;
  45. }
  46. public Map<String, Object> getMaps() {
  47. return maps;
  48. }
  49. public void setMaps(Map<String, Object> maps) {
  50. this.maps = maps;
  51. }
  52. public List<Object> getLists() {
  53. return lists;
  54. }
  55. public void setLists(List<Object> lists) {
  56. this.lists = lists;
  57. }
  58. public Dog getDog() {
  59. return dog;
  60. }
  61. public void setDog(Dog dog) {
  62. this.dog = dog;
  63. }
  64. public Person(String lastName, Integer age, Boolean boss, Date birth, Map<String, Object> maps, List<Object> lists, Dog dog) {
  65. this.lastName = lastName;
  66. this.age = age;
  67. this.boss = boss;
  68. this.birth = birth;
  69. this.maps = maps;
  70. this.lists = lists;
  71. this.dog = dog;
  72. }
  73. @Override
  74. public String toString() {
  75. return "Person{" +
  76. "lastName='" + lastName + '\'' +
  77. ", age=" + age +
  78. ", boss=" + boss +
  79. ", birth=" + birth +
  80. ", maps=" + maps +
  81. ", lists=" + lists +
  82. ", dog=" + dog +
  83. '}';
  84. }
  85. }

3、重启项目,使用浏览器访问 “http://localhost:8081/hello”,结果如下图。


加入
QQ群:722461036
微信群:
一起督促、学习、练习、温习、复习 ~ ~ ~

Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post