繼上一篇博客SpringBoot系列之YAML配置用法之后,再寫一篇@Value、@ConfigurationProperties的對比博客
這兩個主鍵都是可以獲取配置文件屬性的,不過是有比較大的區別的,所以本博客做一下對比,ok,繼續拿上一篇博客的例子來實驗
## 測試ConfigurationProperties
user:
userName: root
isAdmin: true
regTime: 2019/11/01
isOnline: 1
maps: {k1 : v1,k2: v2}
lists:
- list1
- list2
address:
tel: 15899988899
name: 上海市
- 松散綁定(Relaxed binding)
比如例子user: userName也可以表示為user: user-name(大寫用-符號),user: username表示為user: user_name(小寫用_符號),比如支持這種寫法的就是支持松散綁定
例子:
將yml的配置改一下
user:
user-name: root
先用@ConfigurationProperties測試
package org.muses.jeeplatform.bean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Component
@ConfigurationProperties(prefix = "user")
public class User {
private String userName;
private boolean isAdmin;
private Date regTime;
private Long isOnline;
private Map<String,Object> maps;
private List<Object> lists;
private Address address;
@Override
public String toString() {
return "User{" +
"userName='" + userName + '\'' +
", isAdmin=" + isAdmin +
", regTime=" + regTime +
", isOnline=" + isOnline +
", maps=" + maps +
", lists=" + lists +
", address=" + address +
'}';
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public boolean isAdmin() {
return isAdmin;
}
public void setAdmin(boolean admin) {
isAdmin = admin;
}
public Date getRegTime() {
return regTime;
}
public void setRegTime(Date regTime) {
this.regTime = regTime;
}
public Long getIsOnline() {
return isOnline;
}
public void setIsOnline(Long isOnline) {
this.isOnline = isOnline;
}
public Map<String, Object> getMaps() {
return maps;
}
public void setMaps(Map<String, Object> maps) {
this.maps = maps;
}
public List<Object> getLists() {
return lists;
}
public void setLists(List<Object> lists) {
this.lists = lists;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
Junit測試,可以讀到數據
User{userName='root', isAdmin=false, regTime=Fri Nov 01 00:00:00 CST 2019, isOnline=1, maps={k1=v1, k2=v2}, lists=[list1, list2], address=Address{tel='15899988899', name='上海市'}}
改一下,用@Value去讀
user:
userName: root
is-admin: true
@Value("${userName}")
private String userName;
@Value("${is-Admin}")
private boolean isAdmin;
ok,發現報錯了
org.springframework.beans.TypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'boolean'
ok,本博客例子是用application.yml配置的,對於application.properties的本博客沒介紹,不過還是要隨便提一下,application.properties文件的默認文件編碼是utf8,所以寫中文時候有時候會出現亂碼問題
這時候可以修改編碼:file->settings->Editor->file encodings
- SpEL表達式
ok,再對比一下這兩種注解對SpEL表達式的支持,對於SpEL表達式的可以參考:https://blog.csdn.net/fanxiaobin577328725/article/details/68942967
本博客之對比一下,這兩種注解
ok,先改下配置,看看@ConfigurationProperties能獲取到?
user:
isOnline: #{1*1}
debug了一下,發現不能正常計算
ok,驗證@value
@Value("#{1*1}")
private Long isOnline;
junit測試,ok,@Value是支持的
User{userName='null', isAdmin=false, regTime=null, isOnline=1, maps=null, lists=null, address=null}
- JSR303數據校驗
同樣對於JSR303本博客也不進行詳細介紹,詳情可以參考博客:https://www.ibm.com/developerworks/cn/java/j-lo-jsr303/index.html
@ConfigurationProperties驗證:
@AssertTrue
private boolean isAdmin;
junit測試,發現可以支持
@Value驗證
@AssertTrue
@Value("${isAdmin}")
private boolean isAdmin;
驗證,校驗發現不起效
- 復雜類型封裝
ok,驗證@Value是否支持對象類型和list類型,在上篇博客,很顯然驗證了@ConfigurationProperties是支持對象類型和list類型獲取的
所以,本博客驗證一下@Value是否支持就可以
@Value("${maps}")
private Map<String,Object> maps;
junit測試,發現類型轉換錯誤
Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type 'java.lang.String' to required type 'java.util.Map';
綜上,可以歸納一下@Value和@ConfigurationProperties兩種屬性的區別
@ConfigurationProperties | @Value | |
---|---|---|
功能對比 | 批量注入配置文件屬性 | 一個一個屬性的注入 |
松散綁定 | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303數據校驗 | 支持 | 不支持 |
復雜類型封裝 | 支持 | 不支持 |
所以,@ConfigurationProperties適用與注入配置文件整個對應bean的全部屬性,而@Value正如其名稱一樣,適合注入配置文件單個值