Appearance
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