SpringBoot整體讀取多個(gè)配置屬性及其相關(guān)操作方法
上篇文章講到使用@Value注解每次只能讀取一個(gè)配置屬性,若要整體讀取多個(gè)屬性,或者讀取具有某種結(jié)構(gòu)關(guān)系的一組屬性可使用@ConfigurationProperties注解來(lái)處理。
@ConfigurationProperties注解的兩種用法:
- 修飾屬性處理類:當(dāng)@ConfigurationProperties修飾的類被部署為容器中的Bean時(shí),改注解指定的屬性會(huì)被注入該Bean的屬性。因此,@ConfigurationProperties修飾的類稱為“屬性處理類”。
- 修飾@Bean注解修飾的方法:使用@Bean修飾的方法蔣會(huì)配置一個(gè)容器中的Bean,而@ConfigurationProperties指定的屬性會(huì)被注入該Bean的屬性。
看不懂沒(méi)關(guān)系,下面會(huì)有代碼示例。
在使用@ConfigurationProperties時(shí)可指定如下屬性:
- prefix(或value):指定要加載的屬性的前綴
- ignoreInvaildFields():指定是否忽略無(wú)效屬性值。比如處理類定義了某個(gè)字段的類型是Integer,但在配置文件中的值是abc,這就是無(wú)效值。
- ignoreUnknowFields():指定是否忽略未知的字段值。如果在配置文件中配置的屬性比處理類需要的屬性更多,那么多出來(lái)的屬性就是未知屬性。
使用屬性處理類獲取配置屬性
直接來(lái)看代碼示例:
\resources\application.properties文件內(nèi)容:
org.crazyit.enabled=true org.crazyit.name=Crazy Java org.crazyit.remoteAddress=192.168.1.188 org.crazyit.item.brand=Tesla org.crazyit.item.comments=Good, Excellent
(使用IDEA開(kāi)發(fā)屬性處理類時(shí),添加spring-boot-configuration-processor依賴,IDEA會(huì)提供“代碼補(bǔ)全”功能。
<!-- 添加該依賴后IDEA可以提供自動(dòng)補(bǔ)全功能 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
)
SpringBoot不會(huì)自動(dòng)啟用@ConfigurationProperties注解,啟用該注解有如下方式:
- 為@ConfigurationProperties注解修飾的類加@Component注解
- 為@ConfigurationProperties注解修飾的類顯式配置成容器中的bean
- 使用@EnableConfigurationProperties注解,該注解顯式指定一個(gè)或多個(gè)屬性處理類,SpringBoot會(huì)啟用這些屬性處理類上的@ConfigurationProperties注解
- 使用@ConfigurationPropertiesScan注解,該注解指定一個(gè)或多個(gè)包及其子包下所有帶@ConfigurationProperties注解的類
@ConfigurationProperties注解修飾的屬性處理類代碼:
// 指定讀取以org.crazyit.*開(kāi)頭的屬性
@ConfigurationProperties(prefix = "org.crazyit", ignoreUnknownFields=false)
@Component
public class CrazyitProperties
{
// 指定同名的實(shí)例變量和setter方法。SpringBoot會(huì)通過(guò)反射調(diào)用setter方法來(lái)完成屬性值注入
private boolean enabled;
private String name;
private InetAddress remoteAddress;
private final Item item = new Item();
// 省略getter\setter
public static class Item
{
private String brand;
private List<String> comments = new ArrayList<>(Collections.singleton("GREAT"));
// 省略getter\setter
}
}控制器類代碼示例:
@RestController
public class HelloController
{
private final CrazyitProperties crazyitProperties;
// 依賴注入CrazyitProperties屬性處理Bean
@Autowired
public HelloController(CrazyitProperties crazyitProperties)
{
this.crazyitProperties = crazyitProperties;
}
@GetMapping
public CrazyitProperties hello()
{
return crazyitProperties;
}
}運(yùn)行結(jié)果:

屬性處理類也支持使用構(gòu)造器完成屬性值注入,但是要額外使用@ConstructorBinding修飾用于執(zhí)行構(gòu)造注入的構(gòu)造器。注意:使用構(gòu)造器注入,必須使用@EnableConfigurationProperties或者@ConfigurationPropertiesScan注解來(lái)啟用@ConfigurationProperties注解。
屬性處理類示例:
@ConfigurationProperties(prefix = "org.crazyit", ignoreUnknownFields=false)
public class CrazyitProperties
{
private boolean enabled;
private String name;
private InetAddress remoteAddress;
private final Item item;
@ConstructorBinding
public CrazyitProperties(boolean enabled, String name, InetAddress remoteAddress, Item item)
{
this.enabled = enabled;
this.name = name;
this.remoteAddress = remoteAddress;
this.item = item;
}
// 省略getter\setter
public static class Item
{
private String brand;
private List<String> comments = new ArrayList<>(Collections.singleton("GREAT"));
// 省略getter\setter
}
}application.yml
org:
crazyit:
enabled: true
name: 哈利波特
remote-address: 192.168.1.188
item:
brand: Apple
comments:
- Good
- Excellent上面配置的屬性為org.crazyit.remote-address與CrazyitProperties類中定義的remoteAddress屬性不完全相同,SpringBoot能成功注入嗎?
答案是肯定的,因?yàn)镾pringBoot支持寬松綁定(Relaxed Binding)。它不要求配置的屬性名和屬性處理類中的屬性名完全相同。
寬松綁定的四種情況(這4種情況都能完成注入):
- org.crazyit.remote-address
- org.crazyit. remoteAddress
- org.crazyit. remote_address
- ORG_CRAZYIT_REMOTEADDRESS
在*.properties和 *.yml文件中配置List類型的屬性有較小的區(qū)別:
- 在*.properties文件中配置List有2種方式:英文逗號(hào)隔開(kāi)多個(gè)值;用標(biāo)準(zhǔn)方括號(hào)
- 在 *.yml文件中配置List有2種方式:英文逗號(hào)隔開(kāi)多個(gè)值;用短橫線開(kāi)頭(例子所示)
因此,*.properties和 *.yml文件中,都可以用英文逗號(hào)隔開(kāi)多個(gè)值來(lái)構(gòu)建List。
App.java示例
@SpringBootApplication
// 指定掃描org.crazyit.app.config包及其子包下的@ConfigurationProperties注解修飾的類
@ConfigurationPropertiesScan("org.crazyit.app.config")
public class App
{
public static void main(String[] args)
{
// 創(chuàng)建Spring容器、運(yùn)行Spring Boot應(yīng)用
SpringApplication.run(App.class, args);
}
}為容器中的bean注入配置屬性
@ConfigurationProperties注解除了可修飾類,還可修飾@Bean注解修飾的方法。
代碼示例:Book類
public class Book
{
private String title;
private double price;
private String author;
private List<String> keywords;
// 省略getter、setter
}代碼示例:配置類
@Configuration
public class MyConfig
{
@Bean
// @ConfigurationProperties注解會(huì)驅(qū)動(dòng)Spring自動(dòng)調(diào)用該Bean的setter方法
@ConfigurationProperties("fkjava.book")
public Book book()
{
return new Book();
}
}代碼示例:application.yml
fkjava:
book:
title: "美語(yǔ)音標(biāo)"
price: 128
author: "賴世雄"
keywords:
- 英語(yǔ)
- 音標(biāo)代碼示例:控制器類
@RestController
public class HelloController
{
private final Book book;
// 通過(guò)構(gòu)造器注入Book對(duì)象
@Autowired
public HelloController(Book book)
{
this.book = book;
}
@GetMapping
public Book hello()
{
return book;
}
}運(yùn)行結(jié)果:

@Value和 @ConfigurationProperties的對(duì)比
| 特征 | @ConfigurationProperties | @Value |
|---|---|---|
| 注入的屬性個(gè)數(shù) | 批量 | 單個(gè) |
| 寬松綁定 | 支持 | 部分支持 |
| SpEL | 不支持 | 支持 |
| 元數(shù)據(jù)支持 | 支持 | 不支持 |
屬性轉(zhuǎn)換
SpringBoot內(nèi)置了常用的類型轉(zhuǎn)換機(jī)制,如果在轉(zhuǎn)換失敗,則應(yīng)用啟動(dòng)會(huì)失敗,并拋出異常。如果要忽略轉(zhuǎn)換失敗的屬性,可將@ConfigurationProperties注解的ignoreInvaildFields屬性設(shè)為true(默認(rèn)是false)。
SpringBoot可自動(dòng)轉(zhuǎn)換如下類型:Duration、Period、DataSize,并支持為屬性值指定單位。
- Duration類型可指定的單位:ns納秒、μs微妙、ms毫秒、s秒、m分鐘、h小時(shí)、d天。
- Period類型可指定的單位:y年、m月、w星期、d天。(例如配置1y3d,代表1年3天)。
- DataSize類型可指定的單位:B字節(jié)、KB千字節(jié)、MB兆字節(jié)、GB吉字節(jié)、TB太字節(jié)
代碼示例:屬性處理類
// 指定讀取以org.crazyit.*開(kāi)頭的屬性
@ConfigurationProperties(prefix = "org.crazyit")
@Component
public class CrazyitProperties
{
private Duration timeout;
// @DurationUnit注解指定默認(rèn)的時(shí)間單位
@DurationUnit(ChronoUnit.SECONDS)
private Duration lastTime;
private Period runPeriod;
// @DataSizeUnit注解指定默認(rèn)的數(shù)據(jù)單位
@DataSizeUnit(DataUnit.MEGABYTES)
private DataSize maxSize;
// 省略getter、setter
}代碼示例:application.properties
org.crazyit.timeout=30000 # 默認(rèn)單位是秒 org.crazyit.last-time=45 org.crazyit.run-period=2m5d org.crazyit.max-size=2
代碼示例:控制器類
@RestController
public class HelloController
{
private final CrazyitProperties crazyitProperties;
// 依賴注入CrazyitProperties屬性處理Bean
@Autowired
public HelloController(CrazyitProperties crazyitProperties)
{
this.crazyitProperties = crazyitProperties;
}
@GetMapping
public Map<String, Object> hello()
{
System.out.println(crazyitProperties.getMaxSize().toKilobytes());
return Map.of("props", crazyitProperties,
"maxSize", crazyitProperties.getMaxSize().toKilobytes());
}
}運(yùn)行結(jié)果:

校驗(yàn)@ConfigurationProperties
只要為屬性處理類添加@Validated注解,并使用JSR303的校驗(yàn)注解修飾需要校驗(yàn)的示例變量,SpringBoot會(huì)自動(dòng)校驗(yàn)配置文件中的屬性值。如果某個(gè)屬性校驗(yàn)不通過(guò),應(yīng)用會(huì)啟動(dòng)失敗,并用FailureAnalyzer顯式校驗(yàn)錯(cuò)誤。
如果屬性處理類包含復(fù)合類型的屬性,且要對(duì)復(fù)合類型的子屬性進(jìn)行校驗(yàn),則應(yīng)為該復(fù)合類型的屬性添加@Valid注解。
@ConfigurationProperties校驗(yàn)基于JSR303,因此必須添加JSR303依賴,spring-boot-starter-validation依賴庫(kù)包含了JSR303的依賴,因此要在pom文件中添加以下依賴
<!-- 添加Spring Boot Validation依賴庫(kù) --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
屬性處理類示例:
// 指定讀取以org.crazyit.*開(kāi)頭的屬性
@ConfigurationProperties(prefix = "org.crazyit", ignoreUnknownFields=false)
@Component
@Validated
public class CrazyitProperties
{
@NotEmpty
private String name;
@Range(max = 150, min=90, message = "價(jià)格必須位于90~150之間")
private double price;
@Pattern(regexp = "[1][3-8][0-9]{9}", message = "必須輸入有效的手機(jī)號(hào)")
private String mobile;
@Valid
private final Item item = new Item();
// 省略getter setter
public static class Item
{
@Length(min=5, max=10, message = "品牌名長(zhǎng)度必須在5到10個(gè)字符")
private String brand;
@Size(min = 1, message = "comments至少包含一個(gè)元素")
private List<String> comments = new ArrayList<>(Collections.singleton("GREAT"));
// 省略getter、setter
}
}代碼示例:application.properties
org.crazyit.name=Crazy Java org.crazyit.price=89 org.crazyit.mobile=13334444 org.crazyit.item.brand=Apple org.crazyit.item.comments=Great, Excellent
運(yùn)行結(jié)果:

對(duì)于使用@ConfigurationProperties修飾@Bean方法的情況,同樣可對(duì)配置屬性進(jìn)行校驗(yàn),主要為@Bean方法添加@Validated注解即可。
到此這篇關(guān)于SpringBoot整體讀取多個(gè)配置屬性及其相關(guān)操作的文章就介紹到這了,更多相關(guān)SpringBoot讀取多個(gè)配置屬性內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springboot使用@ConfigurationProperties實(shí)現(xiàn)自動(dòng)綁定配置參數(shù)屬性
- SpringBoot3讀取配置文件application.properties屬性值的幾種方式
- SpringBoot高級(jí)配置之臨時(shí)屬性、配置文件、日志、多環(huán)境配置詳解
- SpringBoot測(cè)試配置屬性與web啟動(dòng)環(huán)境超詳細(xì)圖解
- SpringBoot配置文件中密碼屬性加密的實(shí)現(xiàn)
- springboot配置文件屬性變量引用方式${}和@@用法及區(qū)別說(shuō)明
- springboot 自定義配置Boolean屬性不生效的解決
- SpringBoot從配置文件中獲取屬性的四種方法總結(jié)
相關(guān)文章
Mybatis批量修改時(shí)出現(xiàn)報(bào)錯(cuò)問(wèn)題解決方案
這篇文章主要介紹了Mybatis批量修改時(shí)出現(xiàn)報(bào)錯(cuò)問(wèn)題解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11
Java中static和static?final的區(qū)別詳解
這篇文章主要介紹了Java中static和static?final的區(qū)別詳解,開(kāi)發(fā)時(shí)我們經(jīng)常用到static以及static?final來(lái)修飾我們的字段變量,那么他們到底有什么區(qū)別呢?其實(shí)他們的區(qū)別可以用使用字節(jié)碼文件來(lái)解析,需要的朋友可以參考下2023-10-10
Redis中String字符串和sdshdr結(jié)構(gòu)體超詳細(xì)講解
這篇文章主要介紹了Redis中String字符串和sdshdr結(jié)構(gòu)體,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2023-04-04
帶你了解Java數(shù)據(jù)結(jié)構(gòu)和算法之遞歸
這篇文章主要為大家介紹了Java數(shù)據(jù)結(jié)構(gòu)和算法之遞歸,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-01-01
你知道在Java中Integer和int的這些區(qū)別嗎?
最近面試,突然被問(wèn)道,說(shuō)一下Integer和int的區(qū)別.額…可能平時(shí)就知道寫一些業(yè)務(wù)代碼,包括面試的一些Spring源碼等,對(duì)于這種特別基礎(chǔ)的反而忽略了,導(dǎo)致面試的時(shí)候突然被問(wèn)到反而不知道怎么回答了.哎,還是乖乖再看看底層基礎(chǔ),順帶記錄一下把 ,需要的朋友可以參考下2021-06-06
springmvc級(jí)聯(lián)屬性處理無(wú)法轉(zhuǎn)換異常問(wèn)題解決
這篇文章主要介紹了springmvc級(jí)聯(lián)屬性處理無(wú)法轉(zhuǎn)換異常問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12
解決java頁(yè)面URL地址傳輸參數(shù)亂碼的方法
這篇文章主要介紹了解決java頁(yè)面URL地址傳輸參數(shù)亂碼的方法,URL地址參數(shù)亂碼問(wèn)題,算是老話重談了吧!需要的朋友可以參考下2015-09-09
SpringBoot連接Nacos集群報(bào)400問(wèn)題及完美解決方法
這篇文章主要介紹了解決SpringBoot連接Nacos集群報(bào)400問(wèn)題?,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-02-02

