­

SpringBoot系列之@Value和@ConfigurationProperties

  • 2019 年 11 月 3 日
  • 筆記

繼上一篇部落格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正如其名稱一樣,適合注入配置文件單個值