Skip to content

ConfigurationProperties 注解详解

@ConfigurationProperties和@Value注解用于获取配置文件中的属性定义并绑定到Java Bean或属性中

1. 简单使用

java
@Configuration
@ConfigurationProperties(prefix = "mail")
public class ConfigProperties {

private String hostName;
private int port;
private String from;

// standard getters and setters
}

@ConfigurationProperties最适用于所有具有相同前缀的分层属性,用于将配置文件中mail开头的属性绑定到POJO中,@Configuration也可以替换成@Component、@Service等其他注解。

Spring 使用一些宽松的规则来绑定属性。因此,以下变体都绑定到属性hostName:

mail.hostName

mail.hostname

mail.host_name

mail.host-name

mail.HOST_NAME

配置文件内容可以如下(application.properties)

properties
#Simple properties

mail.hostname=host@mail.com

mail.port=9000

mail.from=mailer@mail.com

注:如果没有加@Configuration注解,

需要在主类中添加@EnableConfigurationProperties注解来绑定属性到POJO中,如下:

java
@SpringBootApplication
@EnableConfigurationProperties(ConfigProperties.class)
public class EnableConfigurationDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(EnableConfigurationDemoApplication.class, args);
    }
}

2. 与@ConfigurationPropertiesScan注解一起使用

从Spring Boot 2.2 开始,Spring通过类路径扫描查找并注册@ConfigurationProperties类。因此,不需要使用@Component(以及其他元注释,如@Configuration) 来注释此类类,甚至不需要使用@EnableConfigurationProperties:

java
@ConfigurationProperties(prefix = "mail") 
public class ConfigProperties { 

    private String hostName; 
    private int port; 
    private String from; 
    
    // standard getters and setters 
}

@SpringBootApplication启用的类路径扫描器找到了ConfigProperties类,即使我们没有用@Component注释这个类。

此外,我们可以使用的@ConfigurationPropertiesScan 注释扫描配置属性类的自定义位置:

java
@SpringBootApplication
@ConfigurationPropertiesScan("com.xxx.configurationproperties")
public class EnableConfigurationDemoApplication { 

    public static void main(String[] args) {   
        SpringApplication.run(EnableConfigurationDemoApplication.class, args); 
    } 
}

3. 嵌套属性

我们可以在属性中嵌套List、Map和类

java
//定义Credentials 类
public class Credentials {
    private String authMethod;
    private String username;
    private String password;

    // standard getters and setters
}

我们还需要更新ConfigProperties类使用List、Map和类

java
@Configuration
@ConfigurationProperties(prefix = "mail") 
public class ConfigProperties {

    private String host;
    private int port;
    private String from;
    private List<String> defaultRecipients;
    private Map<String, String> additionalHeaders;
    private Credentials credentials;
    
    // standard getters and setters

}

以下属性文件将设置所有字段:

properties
#Simple properties
mail.hostname=mailer@mail.com
mail.port=9000
mail.from=mailer@mail.com

#List properties
mail.defaultRecipients[0]=admin@mail.com
mail.defaultRecipients[1]=owner@mail.com

#Map Properties
mail.additionalHeaders.redelivery=true
mail.additionalHeaders.secure=true

#Object properties
mail.credentials.username=john
mail.credentials.password=password
mail.credentials.authMethod=SHA1

4. 使用@ConfigurationProperties作用在@Bean注释的方法上

这种方式非常适合绑定到我们无法控制的第三方组件上

java
#Item 类
public class Item {
    private String name;
    private int size;

    // standard getters and setters

}

#将属性绑定到Item实例上

java
@Configuration
public class ConfigProperties {

    @Bean
    @ConfigurationProperties(prefix = "item")
    public Item item() {
        return new Item();
    }
}

5. 不可变的@ConfigurationProperties绑定

    从 Spring Boot 2.2 开始,我们可以使用@ConstructorBinding注释来绑定我们的配置属性。这实质上意味着@ConfigurationProperties注释的类现在可能是不可变的。需要强调的是,要使用构造函数绑定,我们需要使用@EnableConfigurationProperties 或 @ConfigurationPropertiesScan显式启用我们的配置类
java
#ImmutableCredentials 类

@ConfigurationProperties(prefix = "mail.credentials")
@ConstructorBinding
public class ImmutableCredentials {

    private final String authMethod;
    private final String username;
    private final String password;
    
    public ImmutableCredentials(String authMethod, String username, String password) {
        this.authMethod = authMethod;
        this.username = username;
        this.password = password;
    }
    
    public String getAuthMethod() {
        return authMethod;
    }
    
    public String getUsername() {
        return username;
    }
    
    public String getPassword() {
        return password;
    }

}

通过构造器绑定参数,没有提供setter,属性使用final修饰就变成了不可变的属性绑定。

根据以上总结看到@ConfigurationProperties的几种使用方式

方式一:

java
@Configuration  //可以换成@Component
@ConfigurationProperties(prefix = "mail")
public class ConfigProperties {

    private String hostName;
    private int port;
    private String from;
    
    // standard getters and setters

}

方式二:

java
@ConfigurationProperties(prefix = "mail")
public class ConfigProperties {

    private String hostName;
    private int port;
    private String from;
    
    // standard getters and setters

}

@SpringBootApplication
@EnableConfigurationProperties(ConfigProperties.class)
public class EnableConfigurationDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(EnableConfigurationDemoApplication.class, args);
    }
}

注:未指定@Configuration注解,需要在启动类加@EnableConfigurationProperties注解

方式三:

java
@ConfigurationProperties(prefix = "mail")
public class ConfigProperties {

    private String hostName;
    private int port;
    private String from;
    
    // standard getters and setters

}

@SpringBootApplication
@ConfigurationPropertiesScan("com.baeldung.configurationproperties")
public class EnableConfigurationDemoApplication { 

    public static void main(String[] args) {   
        SpringApplication.run(EnableConfigurationDemoApplication.class, args); 
    } 

}

假设ConfigProperties类在com.baeldung.configurationproperties下,直接扫描该包下包含@ConfigurationProperties注解的类

方式四:

java
@Configuration
public class ConfigProperties {

    @Bean
    @ConfigurationProperties(prefix = "item")
    public Item item() {
        return new Item();
    }

}

方式五:

java
@ConfigurationProperties(prefix = "mail.credentials")
@ConstructorBinding
public class ConfigProperties {

  private String hostName;
  private int port;

  private String from;

  public ConfigProperties(String hostName,  int port, String from) {
    this.hostName = hostName;
    this.port = port;
    this.from = from;
  } 

  // standard getters and setters
}

通过以上构造器参数绑定,还需要使用@EnableConfigurationProperties 或 @ConfigurationPropertiesScan显式启用我们的配置类

参考链接: https://blog.csdn.net/skh2015java/article/details/120141409

https://www.baeldung.com/configuration-properties-in-spring-boot