@ConfigurationProperties注解
用于将配置文件(application.properties 或 application.yml)中的配置值,自动绑定到 Java Bean 对象上。
1-1、基本用途
比如我们在 application.yml
中有这样一段配置:
app:name: myAppversion: 1.0.0author: wangsi
我们可以创建一个 Java 配置类来接收它:
@Data
@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {private String name;private String version;private String author;
}
【注意】:
1、属性名要和配置的key一致!
2、prefix=“上一层的key”
然后在其他地方就可以注入这个配置类:
@Autowired
private AppProperties appProperties;
1-2、注解说明
注解 | 作用 |
---|---|
@ConfigurationProperties | 将配置文件中的属性绑定到 Bean |
@Component | 把这个类注入到 Spring 容器中(或在其他配置类中用 @EnableConfigurationProperties 激活) |
1-3、常见用法示例(list集合)
application.yml 配置:
student:name: Lilyage: 22hobbies:- reading- coding
Java 配置类绑定:
@Data
@Component
@ConfigurationProperties(prefix = "student")
public class StudentProperties {private String name;private int age;private List<String> hobbies;
}
1-4、复杂结构绑定(嵌套对象)
server:config:ip: 127.0.0.1port: 8080
@ConfigurationProperties(prefix = "server")
@Component
public class ServerProperties {private Config config;public static class Config {private String ip;private int port;// getters and setters}// getters and setters
}
1-5、与 @Value
对比
特点 | @Value | @ConfigurationProperties |
---|---|---|
使用方式 | 单个字段注入 | 批量绑定到 Bean |
支持类型 | 基本类型 | 支持复杂对象、集合、嵌套结构 |
可维护性 | 差 | 好 |
推荐场景 | 简单常量配置 | 多个配置绑定、模块化配置 |
@ConfigurationProperties
不仅可以为自己定义的配置类绑定属性值,还可以为第三方 Bean 注入配置!
1-6、给第三方类注入配置
假设你要使用一个第三方提供的类 com.alibaba.druid.pool.DruidDataSource
,它不是你自己写的,无法直接加 @Component
。
那怎么把 application.properties
中的配置注入进去呢?
application.yml
在配置类(@Configuration)中注册bean
1、自动注入原理
Spring Boot 在执行 @Bean
方法时,会通过 @ConfigurationProperties
读取 yml 中以指定 prefix
开头的属性,然后自动调用 setter 方法赋值,即:
druidDataSource.setDriverClassName(...);
druidDataSource.setUrl(...);
2、注意事项
DruidDataSource
类必须有 公开的 setter 方法(它有,所以可以绑定)如果是自己写的类,
@ConfigurationProperties
加@Component
;如果是第三方类(不能加
@Component
),那就需要用@Bean + @ConfigurationProperties
来注入配置。
3、额外建议
你也可以把配置提取成一个专门的配置类:
@ConfigurationProperties(prefix = "spring.datasource.druid")
public class DruidConfigProperties {private String driverClassName;private String url;private String username;private String password;// getter/setter
}
然后用:
@Bean
public DruidDataSource dataSource(DruidConfigProperties props) {DruidDataSource ds = new DruidDataSource();ds.setDriverClassName(props.getDriverClassName());ds.setUrl(props.getUrl());...return ds;
}
1-7、@EnableConfigurationProperties
@EnableConfigurationProperties
是 Spring Boot 提供的一个注解,用来启用使用 @ConfigurationProperties
注解的配置类。它常用于你没有在配置类上加 @Component
,但又希望它能被 Spring 管理并注入属性值的场景。
一句话理解:
@EnableConfigurationProperties(SomeConfig.class)
就是让SomeConfig
这个没有加@Component
的类,也能用@ConfigurationProperties
自动注入配置。
举个例子
配置类,没有加 @Component
:
@ConfigurationProperties(prefix = "my.server")
public class ServerProperties {private String name;private Integer port;// getter & setter ...
}
启用它的方式(在配置类中加上):
@Configuration
@EnableConfigurationProperties(ServerProperties.class)
public class AppConfig {
}
配置文件中:
my:server:name: helloport: 8080
1、那和 @Component
有什么区别?
场景 | 推荐做法 |
---|---|
配置类是你自己写的,可以加注解 | 推荐直接用 @Component + @ConfigurationProperties ,简单 |
配置类是三方 jar 里的类,不能加注解 | 用 @EnableConfigurationProperties(SomeClass.class) 来启用 |
有多个配置类,集中统一注册 | 用 @EnableConfigurationProperties({A.class, B.class}) 一次性启用多个 |
2、Spring Boot 推荐方式(官方推荐)
Spring Boot 官方推荐不要在配置类上加 @Component
,而是统一用 @EnableConfigurationProperties
管理配置类,这样职责更清晰(配置类只负责接收配置,不负责成为组件)。
@ConfigurationProperties(prefix = "my.server")
public class ServerProperties {private String name;private Integer port;
}
@Configuration
@EnableConfigurationProperties(ServerProperties.class)
public class AppConfig {
}
3、总结重点
注解 | 作用 |
---|---|
@ConfigurationProperties | 从配置文件注入属性到 Java Bean |
@Component | 把类注册到 Spring 容器(必要才能被注入) |
@EnableConfigurationProperties | 显式注册没有 @Component 的配置类,让其能注入配置 |
1-8、宽松绑定
【注意】:
1、@Value不支持宽松绑定!
2、绑定的前缀命名规范:纯小写字母、数字、下划线(@ConfigurationProperties(presfix="前缀"))
1-9、常用计量单位应用
在 Spring Boot 中,从 2.x 版本开始,配置文件(application.properties
或 application.yml
)中支持使用 JDK 8 提供的时间与数据大小的单位,这使得我们能更直观和简洁地设置各种参数。
1、时间单位(Duration)
Spring Boot 自动支持 Java 8 中的 Duration格式。
常见时间单位
单位 | 示例(YAML) | 示例(Properties) |
---|---|---|
纳秒 | 10ns | timeout=10ns |
微秒 | 10us 或 10µs | timeout=10us |
毫秒 | 10ms | timeout=10ms |
秒 | 10s | timeout=10s |
分钟 | 10m | timeout=10m |
小时 | 10h | timeout=10h |
天 | 10d | timeout=10d |
【示例一】:直接在application配置文件中写上单位
输出结果:
ServerConfig(name=lala, portname=8989, timeoutla=PT0.02S, maxUploadSizela=10485760B)
【示例二】:使用对应的添加单位的注解
返回结果:
ServerConfig(name=lala, portname=8989, timeoutla=PT480H, maxUploadSizela=10240B)
【注意】:
application中的key可以随意写,但是,属性类型要是Duration和DataSize!
2、数据大小单位(DataSize)
Spring Boot 支持 DataSize 类来处理数据大小配置。
常见单位
单位 | 示例(YAML) | 示例(Properties) |
---|---|---|
字节 | 10B | max-size=10B |
KB | 10KB | max-size=10KB |
MB | 10MB | max-size=10MB |
GB | 10GB | max-size=10GB |
TB | 10TB | max-size=10TB |
3、底层机制说明
Spring Boot 的 @ConfigurationProperties
支持将配置属性直接绑定为 Duration
和 DataSize
类型,例如:
@ConfigurationProperties(prefix = "custom")
public class CustomProperties {private Duration timeout;private DataSize maxUploadSize;// getter / setter
}
对应配置:
custom:timeout: 30smax-upload-size: 20MB
注解方式 | 是否支持单位转换 |
---|---|
@ConfigurationProperties | ✅ 支持 |
@Value | ❌ 不支持 |
❌ 注意:@Value 不支持单位转换
如果你用 @Value("${xxx}")
注入,单位不会自动转换:
1-10、开启bean的数据校验(JSR-303规范)
1、添加依赖
2、开启bean的校验功能@Validated
3、在要校验的属性上添加具体的校验规则
常用校验注解
注解 | 说明 |
---|---|
@NotNull | 不能为 null |
@NotEmpty | 字符串/集合不能为 null 或空 |
@NotBlank | 字符串不能为 null 或全空格 |
@Min/@Max | 数值范围限制 |
@Size | 长度/集合大小范围 |
合法邮箱格式 | |
@Pattern | 正则表达式 |
@Positive | 正数 |
@AssertTrue | 必须为 true |
1-11、application配置文件的常见问题:八进制
在 application.yml
文件中,如果你写了一个 前导为 0 的整数(如 0127
)且没有加引号,Spring Boot(底层是 YAML 解析器 SnakeYAML)会将它视为八进制数。
举个例子
port: 0127
这是一个前导 0 的数字。
YAML 规范中,这种写法会被解释为 八进制。
0127
被解释为八进制的127
,即 十进制的 87。
你可以在代码中打印一下看看:
@Value("${port}")
private int port;// 打印出来是 87,而不是 127
1、如何避免这种问题?
给值加引号,让它变成字符串:
port: "0127"
或者:
port: '0127'
YAML 中,加了引号的内容就不会被当成数字解释,而是当成字符串处理。
2、总结
写法 | 解释方式 | 实际数值 |
---|---|---|
0127 | 八进制(0开头:0-7的数字) | 87 |
'0127' | 字符串 | "0127" |
"0127" | 字符串 | "0127" |
所以如果你是想表示 字符串 "0127" 或者整数 127
,就要特别注意加引号或避免前导 0。