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
mail.hostname=host@mail.com
mail.port=9000
mail.from=mailer@mail.com

注:如果没有加@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显式启用我们的配置类

<think>首先,用户的问题是关于"@ConfigurationProperties注解用法详细解释"。用户指定了参考站内引用,包括引用[1]到[5]。我需要基于这些引用内容来回答。 回顾引用内容: - 引用[1]:介绍@ConfigurationProperties注解的背景和重要性,用于绑定配置文件属性到Java对象。 - 引用[2]:用法示例,提到在Configuration类中用@EnableConfigurationProperties启动,在POJO类用@ConfigurationProperties(value="prefix")。 - 引用[3]:提到在Spring Boot中推荐使用@ConfigurationProperties,因为它优于@Value。 - 引用[4]:对比@Value,@ConfigurationProperties可以一次性读取多个属性到JavaBean。 - 引用[5]:涉及内部实现,如调用PropertyResolver.getProperty方法。 用户的需求是详细解释@ConfigurationProperties注解的用法。所以,我需要组织一个清晰的结构,基于这些引用。 根据系统指令: - 所有行内数学表达式必须用$...$,但这里不涉及数学表达式,所以可能不需要。 - 独立公式用$$...$$,同样不适用。 - LaTeX语法正确:这里没有数学内容。 - 使用中文回答。 - 生成相关问题:在回答末尾添加相关问题。 - 引用末尾添加引用标识:例如[^1]。 回答结构应清晰: 1. 介绍注解的背景和作用。 2. 用法细节:如何启用、如何使用在类上。 3. 优点和注意事项。 4. 示例代码。 5. 相关问题。 基于引用: - 启用:在配置类用@EnableConfigurationProperties(引用[2])。 - 使用:在POJO类用@ConfigurationProperties(prefix="prefix")(引用[2])。 - 好处:解耦配置、简化代码(引用[1,4])。 - 注意事项:Spring Boot中推荐使用(引用[3])。 - 示例:显示如何定义属性文件和Java类。 我需要整合这些,确保引用标识正确添加。例如,提到某个点时,加[^数字]。 最后,生成相关问题: - 类似于示例中的快速排序问题,但针对这个主题。 可能的回答大纲: 1. 引言:什么是@ConfigurationProperties注解及其重要性(引用[1])。 2. 用法详解: - 启用注解:@EnableConfigurationProperties - 在POJO类上使用:@ConfigurationProperties(prefix="xxx") - 属性绑定规则 3. 优点:与@Value对比(引用[3,4]) 4. 示例代码 5. 注意事项(引用[2,5]) 6. 结尾:相关问题 相关问题想法: 1. @ConfigurationProperties与@Value的区别是什么? 2. 如何自定义属性绑定? 3. @ConfigurationPropertiesSpring Boot中的最佳实践? 生成代码示例:参考引用[2]和[4],展示一个简单的例子。 </think>### @ConfigurationProperties注解用法详解Spring Boot框架中,@ConfigurationProperties注解是核心工具之一,用于将外部配置文件(如`.properties`或`.yml`文件)中的属性绑定到Java对象上,实现配置的外部化和代码解耦[^1]。它避免了繁琐的@Value注解,尤其适合批量属性映射的场景[^4]。以下从背景、用法、示例到注意事项进行详细解释。 #### 一、背景和重要性 @ConfigurationProperties简化了配置管理,允许开发者将属性集中映射到POJO(Plain Old Java Object)类。这种方式提升了代码可维护性(属性变更无需修改代码)和可扩展性(支持类型安全绑定)[^1]。在Spring Boot中,它被推荐替代@Value注解,因为后者在属性过多时会导致代码臃肿[^3]。 #### 二、用法详解 使用@ConfigurationProperties需要两个关键步骤: 1. **启用注解**:在Spring配置类(通常标记为`@Configuration`的类)中添加`@EnableConfigurationProperties`注解,以激活属性绑定功能[^2]。 2. **定义POJO类**:在目标Java Bean类上添加`@ConfigurationProperties(prefix = "prefix")`,其中`prefix`指定配置文件中属性名的前缀。属性名需与配置文件键名匹配(支持驼峰和下划线自动转换)[^2][^4]。 - **绑定规则**: - 类字段名与配置文件键名(去除前缀后)一一对应。 - 支持嵌套对象:例如,配置文件有`app.database.url`,则POJO类需定义`database`字段(类型为嵌套类)[^4]。 - 类型安全:Spring自动转换字符串到Java类型(如int、List等),无需手动处理[^5]。 #### 三、示例代码 以下是一个完整示例,展示如何读取`application.properties`文件: 1. **配置文件内容** (`application.properties`): ```properties app.name=DemoApp app.version=1.0.0 app.database.url=jdbc:mysql://localhost:3306/test app.database.username=root ``` 2. **POJO类定义**: ```java @ConfigurationProperties(prefix = "app") // 前缀为"app" public class AppConfig { private String name; private String version; private DatabaseConfig database; // 嵌套对象 // Getter和Setter方法(必须提供) public String getName() { return name; } public void setName(String name) { this.name = name; } // ...其他字段的Getter/Setter // 嵌套类定义 public static class DatabaseConfig { private String url; private String username; // Getter/Setter } } ``` 3. **启用配置**: ```java @Configuration @EnableConfigurationProperties(AppConfig.class) // 激活绑定 public class AppConfiguration { } ``` 4. **使用注入**: ```java @Service public class AppService { private final AppConfig appConfig; // 通过构造器注入 public AppService(AppConfig appConfig) { this.appConfig = appConfig; // 直接访问属性,如appConfig.getName() } } ``` #### 四、优点与注意事项 - **优点**: - **简化配置**:一次性映射多个属性,减少@Value的重复代码[^4]。 - **类型安全**:自动处理类型转换(如字符串到集合)[^5]。 - **支持校验**:可与JSR-303验证注解(如@NotNull)结合使用[^2]。 - **注意事项**: - **Getter/Setter必须**:POJO类需提供所有字段的Getter和Setter方法,否则绑定失败[^2]。 - **前缀匹配**:`prefix`必须与配置文件中的键名前缀一致(例如,`prefix="app"`匹配`app.xxx`)[^2]。 - **启动依赖**:仅在Spring Boot应用中有效,需确保`spring-boot-configuration-processor`依赖存在[^3]。 - **性能考虑**:内部调用`PropertySourcesPropertyResolver`解析属性,避免在热路径中使用高频属性[^5]。 #### 五、与其他注解对比 - **vs @Value**:@Value适用于单个属性注入(如`@Value("${app.name}")`),而@ConfigurationProperties更适合批量绑定,减少冗余代码[^3][^4]。 - **结合使用**:可与`@Configuration`或`@Component`结合,但推荐独立POJO类以保持清晰[^1]。 通过以上方式,@ConfigurationProperties显著提升配置管理的效率和可维护性[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值