?@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。