ConfigurationProperties注解详解

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

1.简单使用

@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)

#Simple properties
[email protected]
mail.port=9000
[email protected]

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

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

@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:

@ConfigurationProperties(prefix = "mail") 
public class ConfigProperties {
    
     
 
    private String hostName; 
    private int port; 
    private String from; 
 
    // standard getters and setters 
}

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

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

@SpringBootApplication
@ConfigurationPropertiesScan("com.xxx.configurationproperties")
public class EnableConfigurationDemoApplication {
    
     
 
    public static void main(String[] args) {
    
       
        SpringApplication.run(EnableConfigurationDemoApplication.class, args); 
    } 
}

3. 嵌套属性

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

//定义Credentials 类
public class Credentials {
    
    
    private String authMethod;
    private String username;
    private String password;
 
    // standard getters and setters
}

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

@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
}

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

#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注释的方法上

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

#Itempublic class Item {
    
    
    private String name;
    private int size;
 
    // standard getters and setters
}
 
#将属性绑定到Item实例上
@Configuration
public class ConfigProperties {
    
    
 
    @Bean
    @ConfigurationProperties(prefix = "item")
    public Item item() {
    
    
        return new Item();
    }
}

5. 不可变的@ConfigurationProperties绑定

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

#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修饰就变成了不可变的属性绑定。

6.总结

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

@Configuration  //可以换成@Component
@ConfigurationProperties(prefix = "mail")
public class ConfigProperties {
    
    
    
    private String hostName;
    private int port;
    private String from;
 
    // standard getters and setters
}

方式二:

@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注解

方式三:

@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注解的类

方式四:

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

方式五:

@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显式启用我们的配置类

猜你喜欢

转载自blog.csdn.net/doublepg13/article/details/128563455