Spring Boot2.0 @ConfigurationProperties使用詳解
引言
Spring Boot的一個便捷功能是外部化配置,可以輕松訪問屬性文件中定義的屬性。本文將詳細(xì)介紹@ConfigurationProperties的使用。
配置項(xiàng)目POM
在pom.xml中定義Spring-Boot 為parent
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent>
添加依賴
- 添加web,因?yàn)槲覀冃枰褂玫絁SR-303規(guī)范的Validator,如果不想使用web依賴,也可以直接依賴hibernate-validator
- 添加spring-boot-configuration-processor,可以在編譯時生成屬性元數(shù)據(jù)(spring-configuration-metadata.json).
- 添加lombok,可以方便使用注釋處理器的功能省去Pojo定義中g(shù)et set這些麻煩工作.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--<dependency>--> <!--<groupId>org.hibernate.validator</groupId>--> <!--<artifactId>hibernate-validator</artifactId>--> <!--<version>6.0.11.Final</version>--> <!--<scope>compile</scope>--> <!--</dependency>--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
例子編寫
首先定義一個DocumentServerProperties對象,下面這個文檔服務(wù)器配置是我假設(shè)的,主要是為了演示屬性配置的大部分情況
@Getter
@Setter
public class DocumentServerProperties {
private String remoteAddress;
private boolean preferIpAddress;
private int maxConnections=0;
private int port;
private AuthInfo authInfo;
private List<String> whitelist;
private Map<String,String> converter;
private List<Person> defaultShareUsers;
@Getter
@Setter
public static class AuthInfo {
private String username;
private String password;
}
}
綁定屬性配置
注意@ConfigurationProperties并沒有把當(dāng)前類注冊成為一個Spring的Bean,下面介紹@ConfigurationProperties配置注入的三種方式.
配合@Component注解直接進(jìn)行注入
@ConfigurationProperties(prefix = "doc")
@Component
public class DocumentServerProperties {
//代碼...
}
使用@EnableConfigurationProperties,通常配置在標(biāo)有@Configuration的類上,當(dāng)然其他@Component注解的派生類也可以,不過不推薦.
@ConfigurationProperties(prefix = "doc")
public class DocumentServerProperties {
//代碼...
}
@EnableConfigurationProperties
@Configuration
public class SomeConfiguration {
private DocumentServerProperties documentServerProperties
public SomeConfiguration(DocumentServerProperties documentServerProperties) {
this.documentServerProperties = documentServerProperties;
}
}
使用@Bean方式在標(biāo)有@Configuration的類進(jìn)行注入,這種方式通??梢杂迷趯Φ谌筋愡M(jìn)行配置屬性注冊
@Configuration
public class SomeConfiguration {
@Bean
public DocumentServerProperties documentServerProperties(){
return new DocumentServerProperties();
}
@ConfigurationProperties("demo.third")
@Bean
public ThirdComponent thirdComponent(){
return new ThirdComponent();
}
}
編寫配置文件
Spring-Boot中配置文件的格式有properties和yaml兩種格式,針對上面的配置對象分別寫了兩種格式的配置文件例子.
Properties
doc.remote-address=127.0.0.1 doc.port=8080 doc.max-connections=30 doc.prefer-ip-address=true #doc.whitelist=192.168.0.1,192.168.0.2 # 這種等同于下面的doc.whitelist[0] doc.whitelist[1] doc.whitelist[0]=192.168.0.1 doc.whitelist[1]=192.168.0.2 doc.default-share-users[0].name=jack doc.default-share-users[0].age=18 doc.converter.a=xxConverter doc.converter.b=xxConverter doc.auth-info.username=user doc.auth-info.password=password
Yaml
doc: remote-address: 127.0.0.1 port: 8080 max-connections: 30 prefer-ip-address: true whitelist: - 192.168.0.1 - 192.168.0.2 default-share-users: - name: jack age: 18 converter: a: aConverter b: bConverter auth-info: username: user password: password
在上面的兩個配置文件中,其實(shí)已經(jīng)把我們平常大部分能使用到的屬性配置場景都覆蓋了,可能還有一些特殊的未介紹到,比如Duration、InetAddress等。
增加屬性驗(yàn)證
下面我們利用JSR303規(guī)范的實(shí)現(xiàn)對DocumentServerProperties屬性配置類,添加一些常規(guī)驗(yàn)證,比如Null檢查、數(shù)字校驗(yàn)等操作,
需要注意在Spring-Boot 2.0版本以后,如果使用JSR303對屬性配置進(jìn)行驗(yàn)證必須添加@Validated注解,使用方式如下片段:
@ConfigurationProperties(prefix = "doc")
@Validated
public class DocumentServerProperties {
@NotNull // 判斷不為空的情況
private String remoteAddress;
//限制端口只能是80-65536之間
@Min(80)
@Max(65536)
private int port;
//其他代碼
}
在有些數(shù)情況下,我們希望自定義驗(yàn)證器,有兩種方式可以進(jìn)行實(shí)現(xiàn)
實(shí)現(xiàn)org.springframework.validation.Validator接口,并且在配置一個Bean名稱必須叫configurationPropertiesValidator,代碼如下:
public class UserLoginValidator implements Validator {
private static final int MINIMUM_PASSWORD_LENGTH = 6;
public boolean supports(Class clazz) {
return UserLogin.class.isAssignableFrom(clazz);
}
public void validate(Object target, Errors errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "userName", "field.required");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password", "field.required");
UserLogin login = (UserLogin) target;
if (login.getPassword() != null
&& login.getPassword().trim().length() < MINIMUM_PASSWORD_LENGTH) {
errors.rejectValue("password", "field.min.length",
new Object[]{Integer.valueOf(MINIMUM_PASSWORD_LENGTH)},
"The password must be at least [" + MINIMUM_PASSWORD_LENGTH + "] characters in );
}
}
}
和上面一樣也是實(shí)現(xiàn)org.springframework.validation.Validator接口,不過是需要驗(yàn)證的屬性配置類本身去實(shí)現(xiàn)這個接口
@ConfigurationProperties(prefix = "doc")
public class DocumentServerProperties implements Validator{
@NotNull
private String remoteAddress;
private boolean preferIpAddress;
//其他屬性
@Override
public boolean supports(Class<?> clazz) {
return true;
}
@Override
public void validate(Object target, Errors errors) {
//判斷邏輯其實(shí)可以參照上面的代碼片段
}
}
特別注意:
- 只有在需要使用JSR303規(guī)范實(shí)現(xiàn)的驗(yàn)證器時,才需要對對象配置@Validated,剛剛上面兩種方式并不需要。
- 第一種實(shí)現(xiàn)和第二種實(shí)現(xiàn)都是實(shí)現(xiàn)org.springframework.validation.Validator接口,但是前者是針對全局的,后者只針對實(shí)現(xiàn)這個接口的配置對象
關(guān)于上述兩點(diǎn),我為啥確定? 來自ConfigurationPropertiesBinder的源碼片段
private List<Validator> getValidators(Bindable<?> target) {
List<Validator> validators = new ArrayList<>(3);
if (this.configurationPropertiesValidator != null) {
validators.add(this.configurationPropertiesValidator);
}
if (this.jsr303Present && target.getAnnotation(Validated.class) != null) {
validators.add(getJsr303Validator());
}
if (target.getValue() != null && target.getValue().get() instanceof Validator) {
validators.add((Validator) target.getValue().get());
}
return validators;
}
總結(jié)
通過上面的例子,我們了解了@ConfigurationProperties的使用以及如何進(jìn)行驗(yàn)證,包括屬性驗(yàn)證器的幾種實(shí)現(xiàn)方式.下個章節(jié)我會從源碼的角度分析屬性的加載,以及如何解析到Bean里面去的。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- springboot如何使用@ConfigurationProperties封裝配置文件
- @ConfigurationProperties遇到的坑及解決
- springboot @ConfigurationProperties和@PropertySource的區(qū)別
- SpringBoot @ConfigurationProperties注解的簡單使用
- 詳解@ConfigurationProperties實(shí)現(xiàn)原理與實(shí)戰(zhàn)
- @ConfigurationProperties綁定配置信息至Array、List、Map、Bean的實(shí)現(xiàn)
- SpringBoot @ConfigurationProperties使用詳解
- Java中@ConfigurationProperties實(shí)現(xiàn)自定義配置綁定問題分析
相關(guān)文章
教你如何把Eclipse創(chuàng)建的Web項(xiàng)目(非Maven)導(dǎo)入Idea
這篇文章主要介紹了教你如何把Eclipse創(chuàng)建的Web項(xiàng)目(非Maven)導(dǎo)入Idea,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-04-04
基于Spring Boot的Environment源碼理解實(shí)現(xiàn)分散配置詳解
這篇文章主要給大家介紹了基于Spring Boot的Environment源碼理解實(shí)現(xiàn)分散配置的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-08-08
使用IntelliJ IDEA2020.2.2 x64 新建java項(xiàng)目并且輸出Hello World
這篇文章主要介紹了使用IntelliJ IDEA2020.2.2 x64 新建java項(xiàng)目并且輸出Hello World,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
Java PriorityQueue優(yōu)點(diǎn)和缺點(diǎn)面試精講
這篇文章主要為大家介紹了Java面試中PriorityQueue的優(yōu)點(diǎn)和缺點(diǎn)及使用注意詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10
Spring?Boot項(xiàng)目集成Knife4j接口文檔的實(shí)例代碼
Knife4j就相當(dāng)于是swagger的升級版,對于我來說,它比swagger要好用得多<BR>,這篇文章主要介紹了Spring?Boot項(xiàng)目集成Knife4j接口文檔的示例代碼,需要的朋友可以參考下2021-12-12

