SpringBoot 配置绑定

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

SpringBoot 提供了以下 2 种方式进行配置绑定:

  • 使用@ConfigurationProperties注解
  • 使用@Value注解

@ConfigurationProperties

@ConfigurationProperties注解可以将全局配置文件中的配置数据绑定到JavaBean中。

  1. 全局配置文件appilcation.yml中添加以下自定义属性。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    person:
    lastName: 张三
    age: 18
    boss: false
    birth: 1990/12/12
    maps: { k1: v1,k2: 12 }
    lists:
    ‐ lisi
    ‐ zhaoliu
    dog:
    name: 迪迪
    age: 5
  2. net.biancheng.www.bean中创建一个名为Person的实体类,并将配置文件中的属性映射到这个实体类上。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    package net.biancheng.www.bean;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.stereotype.Component;
    import java.util.Date;
    import java.util.List;
    import java.util.Map;
    /**
    * 将配置文件中配置的每一个属性的值,映射到这个组件中
    *
    * @ConfigurationProperties:告诉 SpringBoot 将本类中的所有属性和配置文件中相关的配置进行绑定;
    * prefix = "person":配置文件中哪个下面的所有属性进行一一映射
    *
    * 只有这个组件是容器中的组件,才能使用容器提供的@ConfigurationProperties功能;
    */
    @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;
    public Person() {
    }
    public String getLastName() {
    return lastName;
    }
    public void setLastName(String lastName) {
    this.lastName = lastName;
    }
    public Integer getAge() {
    return age;
    }
    public void setAge(Integer age) {
    this.age = age;
    }
    public Boolean getBoss() {
    return boss;
    }
    public void setBoss(Boolean boss) {
    this.boss = boss;
    }
    public Date getBirth() {
    return birth;
    }
    public void setBirth(Date birth) {
    this.birth = birth;
    }
    public Map<String, Object> getMaps() {
    return maps;
    }
    public void setMaps(Map<String, Object> maps) {
    this.maps = maps;
    }
    public List<Object> getLists() {
    return lists;
    }
    public void setLists(List<Object> lists) {
    this.lists = lists;
    }
    public Dog getDog() {
    return dog;
    }
    public void setDog(Dog dog) {
    this.dog = dog;
    }
    public Person(String lastName, Integer age, Boolean boss, Date birth, Map<String, Object> maps, List<Object> lists, Dog dog) {
    this.lastName = lastName;
    this.age = age;
    this.boss = boss;
    this.birth = birth;
    this.maps = maps;
    this.lists = lists;
    this.dog = dog;
    }
    @Override
    public String toString() {
    return "Person{" +
    "lastName='" + lastName + '\'' +
    ", age=" + age +
    ", boss=" + boss +
    ", birth=" + birth +
    ", maps=" + maps +
    ", lists=" + lists +
    ", dog=" + dog +
    '}';
    }
    }
    注意:
  • 只有在容器中的组件,才会拥有 SpringBoot 提供的强大功能。如果我们想要使用@ConfigurationProperties注解进行配置绑定,那么首先就要保证该JavaBean对象在 IoC 容器中,所以需要用到@Component注解来添加组件到容器中。
  • JavaBean上使用了注解@ConfigurationProperties(prefix = "person"),它表示将这个JavaBean中的所有属性与配置文件中以person为前缀的配置进行绑定。
  1. net.biancheng.www.bean中,创建一个名为DogJavaBean
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    package net.biancheng.www.bean;
    public class Dog {
    private String name;
    private String age;
    public Dog() {
    }
    public Dog(String name, String age) {
    this.name = name;
    this.age = age;
    }
    public void setName(String name) {
    this.name = name;
    }
    public void setAge(String age) {
    this.age = age;
    }
    public String getName() {
    return name;
    }
    public String getAge() {
    return age;
    }
    }
  2. 修改HelloController的代码,在浏览器中展示配置文件中各个属性值。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    package net.biancheng.www.controller;
    import net.biancheng.www.bean.Person;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    @Controller
    public class HelloController {
    @Autowired
    private Person person;
    @ResponseBody
    @RequestMapping("/hello")
    public Person hello() {
    return person;
    }
    }
  3. 重启项目,使用浏览器访问http://localhost:8081/hello

@Value

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

  1. 修改实体类Person中的代码,使用@Value注解进行配置绑定。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    package net.biancheng.www.bean;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.stereotype.Component;
    import java.util.Date;
    import java.util.List;
    import java.util.Map;
    @Component
    public class Person {
    @Value("${person.lastName}")
    private String lastName;
    @Value("${person.age}")
    private Integer age;
    @Value("${person.boss}")
    private Boolean boss;
    @Value("${person.birth}")
    private Date birth;
    private Map<String, Object> maps;
    private List<Object> lists;
    private Dog dog;
    public Person() {
    }
    // getter和setter
    // ...
    }
  2. 重启项目,使用浏览器访问http://localhost:8081/hello

@Value 与 @ConfigurationProperties 对比

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

  1. 使用位置不同
  • @ConfigurationProperties:标注在JavaBean的类名上;
  • @Value:标注在JavaBean的属性上。
  1. 功能不同
  • @ConfigurationProperties:用于批量绑定配置文件中的配置;
  • @Value:只能一个一个的指定需要绑定的配置。
  1. 松散绑定支持不同
  • @ConfigurationProperties:支持松散绑定(松散语法),例如实体类Person中有一个属性为firstName,那么配置文件中的属性名支持以下写法:
    1
    2
    3
    4
    person.firstName
    person.first-name
    person.first_name
    PERSON_FIRST_NAME
  • @Vaule:不支持松散绑定。
  1. SpEL 支持不同
  • @ConfigurationProperties:不支持 SpEL 表达式;
  • @Value:支持 SpEL 表达式。
  1. 复杂类型封装
  • @ConfigurationProperties:支持所有类型数据的封装,例如Map、List、Set、以及对象等;
  • @Value:只支持基本数据类型的封装,例如字符串、布尔值、整数等类型。
  1. 应用场景不同
    @Value@ConfigurationProperties两个注解之间,并没有明显的优劣之分,它们只是适合的应用场景不同而已。
  • 若只是获取配置文件中的某项值,则推荐使用@Value注解;
  • 若专门编写了一个 JavaBean 来和配置文件进行映射,则建议使用 @ConfigurationProperties 注解。

我们在选用时,根据实际应用场景选择合适的注解能达到事半功倍的效果。

@PropertySource

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

  1. helloworld为例,将与person相关的自定义配置移动到src/main/resources下的person.properties中。
    person.properties的配置如下。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    person.last-name=李四
    person.age=12
    person.birth=2000/12/15
    person.boss=false
    person.maps.k1=v1
    person.maps.k2=14
    person.lists=a,b,c
    person.dog.name=dog
    person.dog.age=2
  2. Person使用@PropertySource注解指向person.properties
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    package net.biancheng.www.bean;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.PropertySource;
    import org.springframework.stereotype.Component;
    import java.util.Date;
    import java.util.List;
    import java.util.Map;
    @PropertySource(value = "classpath:person.properties")//指向对应的配置文件
    @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;
    public Person() {
    }
    // getter和setter
    // ...
    }
  3. 重启项目,使用浏览器访问http://localhost:8081/hello
打赏
  • Copyrights © 2017-2023 WSQ
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信