spring boot · 2019-12-16 0

SpringBoot使用@ConfigurationProperties和@EnableConfigurationProperties

一、pom 依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.2.RELEASE</version>
    <relativePath/>
</parent>

<dependencies>

    <!-- spring-boot-starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <!-- 导入配置文件处理器 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
    </dependency>

</dependencies>

二、代码

1.配置文件

application.yml

person:
  name: 古力娜扎
  age: 27

2. 使用 @Component 注册

使用 @Component,注册 bean,只有这个组件是容器中的组件,才能容器提供的@ConfigurationProperties功能,将配置文件中配置的每一个属性的值,映射到这个组件中

@ConfigurationProperties:告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定 ,prefix = "person":配置文件中哪个下面的属性进行一一映射

@Component
@ConfigurationProperties(prefix = "person")
public class PersonProperties {

    private String name;

    private int age;

    @Override
    public String toString() {
        return "PersonProperties{" +
                "name='" + name + ''' +
                ", age=" + age +
                '}';
    }

    // set、get方法
}
@SpringBootApplication
public class Boot {

    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(Boot.class, args);
        PersonProperties personProperties = context.getBean(PersonProperties.class);
        System.out.println(personProperties);
    }
}

3. 使用 @EnableConfigurationProperties 注册

或可使用 @EnableConfigurationProperties 注册 bean

@ConfigurationProperties(prefix = "person")
public class PersonProperties {

    private String name;

    private int age;

    @Override
    public String toString() {
        return "PersonProperties{" +
                "name='" + name + ''' +
                ", age=" + age +
                '}';
    }

    // set、get方法
}
@EnableConfigurationProperties(PersonProperties.class)
@SpringBootApplication
public class Boot {

    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(Boot.class, args);
        PersonProperties personProperties = context.getBean(PersonProperties.class);
        System.out.println(personProperties);
    }
}

4.结果

结果:

PersonProperties{name='古力娜扎', age=27}

三、原理

配置类在实例化之前,会执行 ConfigurationPropertiesBindingPostProcessor 的 postProcessBeforeInitialization 方法,把配置类赋值

// ConfigurationPropertiesBindingPostProcessor.java

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    bind(ConfigurationPropertiesBean.get(this.applicationContext, bean, beanName));
    return bean;
}

private void bind(ConfigurationPropertiesBean bean) {
    ...
    this.binder.bind(bean);
    ...
}
// ConfigurationPropertiesBinder.java

BindResult<?> bind(ConfigurationPropertiesBean propertiesBean) {
    Bindable<?> target = propertiesBean.asBindTarget();
    ConfigurationProperties annotation = propertiesBean.getAnnotation();
    BindHandler bindHandler = getBindHandler(target, annotation);
    return getBinder().bind(annotation.prefix(), target, bindHandler);
}