1. 程式人生 > >Spring Boot配置檔案詳解-ConfigurationProperties和Value優缺點-(轉)好文

Spring Boot配置檔案詳解-ConfigurationProperties和Value優缺點-(轉)好文

文章轉自 http://www.cnblogs.com/itdragon/p/8686554.html

Spring Boot提供了兩種常用的配置檔案,分別是properties檔案和yml檔案。他們的作用都是修改Spring Boot自動配置的預設值。相對於properties檔案而言,yml檔案更年輕,也有很多的坑。可謂成也蕭何敗也蕭何,yml通過空格來確定層級關係,使配置檔案結構更清晰,但也會因為微不足道的空格而破壞了層級關係。本章重點介紹yml的語法和從配置檔案中取值。還在等什麼,趕快來學習吧!

技術:yaml、properties語法,ConfigurationProperties和Value註解的使用,配置檔案佔位符的使用

說明:本章重點介紹yaml的語法和ConfigurationProperties註解的使用,測試程式碼和完整程式碼請移步github,喜歡的朋友可以點個star。

原始碼:https://github.com/ITDragonBlog/daydayup/tree/master/SpringBoot/spring-boot-yml

文章目錄結構:

一、YAML簡介

yml是YAML(YAML Ain't Markup Language)語言的檔案,以資料為中心,比json、xml等更適合做配置檔案

yml和xml相比,少了一些結構化的程式碼,使資料更直接,一目瞭然。

yml和json呢?沒有誰好誰壞,合適才是最好的。yml的語法比json優雅,註釋更標準,適合做配置檔案。json作為一種機器交換格式比yml強,更適合做api呼叫的資料交換。

一)YAML語法

以空格的縮排程度來控制層級關係。空格的個數並不重要,只要左邊空格對齊則視為同一個層級。注意不能用tab代替空格。且大小寫敏感。支援字面值,物件,陣列三種資料結構,也支援複合結構。

字面值:字串,布林型別,數值,日期。字串預設不加引號,單引號會轉義特殊字元。日期格式支援yyyy/MM/dd HH:mm:ss

物件:由鍵值對組成,形如 key:(空格)value 的資料組成。冒號後面的空格是必須要有的,每組鍵值對佔用一行,且縮排的程度要一致,也可以使用行內寫法:{k1: v1, ....kn: vn}

陣列:由形如 -(空格)value 的資料組成。短橫線後面的空格是必須要有的,每組資料佔用一行,且縮排的程度要一致,也可以使用行內寫法: [1,2,...n]

複合結構:上面三種資料結構任意組合

二)YAML的運用

建立一個Spring Boot 的全域性配置檔案 application.yml,配置屬性引數。主要有字串,帶特殊字元的字串,布林型別,數值,集合,行內集合,行內物件,集合物件這幾種常用的資料格式。

yaml:
  str: 字串可以不加引號
  specialStr: "雙引號直接輸出\n特殊字元"  specialStr2: '單引號可以轉義\n特殊字元'  flag: false  num: 666  Dnum: 88.88  list:  - one  - two  - two  set: [1,2,2,3]  map: {k1: v1, k2: v2}  positions:  - name: ITDragon  salary: 15000.00  - name: ITDragonBlog  salary: 18888.88

建立實體類YamlEntity.java 獲取配置檔案中的屬性值,通過註解@ConfigurationProperties獲取配置檔案中的指定值並注入到實體類中。其具體的測試方法和獲取值的原理,請繼續往後看!

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.Set; /** * YAML 語法實體類 * 切記點: * 一、冒號後面加空格,即 key:(空格)value * 二、每行引數左邊空格數量決定了該引數的層級,不可亂輸入。 */ @Component @ConfigurationProperties(prefix = "yaml") public class YamlEntity { // 字面值,字串,布林,數值 private String str; // 普通字串 private String specialStr; // 轉義特殊字串 private String specialStr2;// 輸出特殊字串 private Boolean flag; // 布林型別 private Integer num; // 整數 private Double dNum; // 小數 // 陣列,List和Set,兩種寫法: 第一種:-空格value,每個值佔一行,需縮排對齊;第二種:[1,2,...n] 行內寫法 private List<Object> list; // list可重複集合 private Set<Object> set; // set不可重複集合 // Map和實體類,兩種寫法:第一種:key空格value,每個值佔一行,需縮排對齊;第二種:{key: value,....} 行內寫法 private Map<String, Object> map; // Map K-V private List<Position> positions; // 複合結構,集合物件 // 省略getter,setter,toString方法 }

三)YML小結

一、字串可以不加引號,若加雙引號則輸出特殊字元,若不加或加單引號則轉義特殊字元;

二、陣列型別,短橫線後面要有空格;物件型別,冒號後面要有空格;

三、YAML是以空格縮排的程度來控制層級關係,但不能用tab鍵代替空格,大小寫敏感;

四、如何讓一個程式設計師崩潰?在yml檔案中加幾個空格!(〃>皿<)

二、Properties簡介

properties檔案大家經常用,這裡就簡單介紹一下。其語法結構形如:key=value。注意中文亂碼問題,需要轉碼成ASCII。具體如下所示:

userinfo.account=itdragonBlog
userinfo.age=25
userinfo.active=true
userinfo.created-date=2018/03/31 16:54:30 userinfo.map.k1=v1 userinfo.map.k2=v2 userinfo.list=one,two,three userinfo.position.name=Java架構師 userinfo.position.salary=19999.99

從配置檔案中取值注入到實體類中,和YAML是一樣的。

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map; /** * 使用者資訊 * @ConfigurationProperties : 被修飾類中的所有屬性會和配置檔案中的指定值(該值通過prefix找到)進行繫結 */ @Component @ConfigurationProperties(prefix = "userinfo") public class UserInfo { private String account; private Integer age; private Boolean active; private Date createdDate; private Map<String, Object> map; private List<Object> list; private Position position; // 省略getter,setter,toString方法 }

三、配置檔案取值

Spring Boot通過ConfigurationProperties註解從配置檔案中獲取屬性。從上面的例子可以看出ConfigurationProperties註解可以通過設定prefix指定需要批量匯入的資料。支援獲取字面值,集合,Map,物件等複雜資料。ConfigurationProperties註解還有其他特麼呢?它和Spring的Value註解又有什麼區別呢?帶著這些問題,我們繼續往下看。(๑•̀ㅂ•́)و✧

一)ConfigurationProperties和Value優缺點

ConfigurationProperties註解的優缺點

一、可以從配置檔案中批量注入屬性;

二、支援獲取複雜的資料型別;

三、對屬性名匹配的要求較低,比如user-name,user_name,userName,USER_NAME都可以取值;

四、支援JAVA的JSR303資料校驗;

五、缺點是不支援強大的SpEL表示式;

Value註解的優缺點正好相反,它只能一個個配置注入值;不支援陣列、集合等複雜的資料型別;不支援資料校驗;對屬性名匹配有嚴格的要求。最大的特點是支援SpEL表示式,使其擁有更豐富的功能。

二)@ConfigurationProperties詳解

第一步:匯入依賴。若要使用ConfigurationProperties註解,需要匯入依賴 spring-boot-configuration-processor;

第二步:配置資料。在application.yml配置檔案中,配置屬性引數,其字首為itdragon,引數有字面值和陣列,用來判斷是否支援獲取複雜屬性的能力;

第三步:匹配資料。在類上添加註解ConfigurationProperties,並設定prefix屬性值為itdragon。並把該類新增到Spring的IOC容器中。

第四步:校驗資料。新增資料校驗Validated註解,開啟資料校驗,測試其是否支援資料校驗的功能;

第五步:測試ConfigurationProperties註解是否支援SpEL表示式;

匯入依賴:pom.xml 新增 spring-boot-configuration-processor依賴

<dependency>
  <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>

配置資料:application.yml 配置屬性引數,nick-name是用來判斷匹配屬性的鬆散性,若換成nick_name依然可以獲取值。

itdragon:
  nick-name: ITDragonBlog
  email: 1234567890@qq.com  iphone: 1234567890  abilities: [java, sql, html]  created_date: 2018/03/31 15:27:30

匹配和校驗資料:

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.Email;
import java.util.Date; import java.util.List; /** * ConfigurationProperties 註解語法類 * 第一步:匯入依賴 spring-boot-configuration-processor; * 第二步:把ConfigurationProperties註解修飾的類新增到Spring的IOC容器中; * 第三步:設定prefix屬性,指定需要注入屬性的字首; * 第四步:新增資料校驗註解,開啟資料校驗; * * 注意點: * 一、nickName和createdDate在yml配置檔案中,對應引數分別是中劃線和下劃線,用於測試其對屬性名匹配的鬆散性 * 二、email和iphone 測試其支援JSR303資料校驗 * 三、abilities 測試其支援複雜的資料結構 */ @Component @ConfigurationProperties(prefix = "itdragon") @Validated public class ConfigurationPropertiesEntity { private String nickName; // 解析成功,支援鬆散匹配屬性 private String email; // @Email // 解析失敗,資料校驗成功:BindValidationException: Binding validation errors on itdragon private String iphone; private List<String> abilities; private Date createdDate; // 解析成功,支援鬆散匹配屬性 // @ConfigurationProperties("#{(1+2-3)/4*5}") private String operator; // 語法報錯,不支援SpEL表示式:not applicable to field // 省略getter,setter,toString方法 }

三)@Value詳解

上一篇部落格已經介紹過Value註解的使用,這裡只簡單說明。

第一步:在屬性上新增Value註解,通過${}設定引數從配置檔案中注入值;

第二步:修改${itdragon.ceatred_date}中的引數值,改為${itdragon.ceatredDate}測試是否能解析成功;

第三步:新增資料校驗Validated註解,開啟資料校驗,測試其是否支援資料校驗的功能;

第四步:測試Value註解是否支援SpEL表示式;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.Email;
import java.util.Date; import java.util.List; /** * Value 註解語法類 * 第一步:在屬性上添加註解Value注入引數 * 第二步:把Value註解修飾的類新增到Spring的IOC容器中; * 第三步:新增資料校驗註解,檢查是否支援資料校驗; * * 注意點: * 一、nickName和createdDate在yml配置檔案中,對應引數分別是中劃線和下劃線,用於測試其對屬性名匹配的鬆散性 * 二、email和iphone 測試其支援JSR303資料校驗 * 三、abilities 測試其支援複雜的資料結構 * * 結論: * 一、createDate取值必須和yml配置檔案中的引數保持一致, * 二、既是在iphone上新增郵箱驗證註解依然可以通過測試, * 三、不支援複雜的資料結構,提示錯誤和第一條相同:IllegalArgumentException: Could not resolve placeholder 'itdragon.abilities' in value "${itdragon.abilities}" */ @Component @Validated public class ValueEntity { @Value("${itdragon.nick-name}") private String nickName; @Value("${itdragon.email}") private String email; @Email @Value("${itdragon.iphone}") // 解析成功,並不支援資料校驗 private String iphone; // @Value("${itdragon.abilities}") // 解析錯誤,並不支援複雜的資料結構 private List<String> abilities; // @Value("${itdragon.ceatredDate}") // 解析錯誤,並不支援鬆散匹配屬性,必須嚴格一致 private Date createdDate; // Value註解的強大一面:支援SpEL表示式 @Value("#{(1+2-3)/4*5}") // 算術運算 private String operator; @Value("#{1>2 || 2 <= 3}") // 關係運算 private Boolean comparison; @Value("#{systemProperties['java.version']}") // 系統配置:os.name private String systemProperties; @Value("#{T(java.lang.Math).abs(-18)}") // 表示式 private String mapExpression; // 省略getter,setter,toString方法 }

四)配置檔案取值小結

一、ConfigurationProperties註解支援批量注入,而Value註解適合單個注入;

二、ConfigurationProperties註解支援資料校驗,而Value註解不支援;

三、ConfigurationProperties註解支援鬆散匹配屬性,而Value註解必須嚴格匹配屬性;

四、ConfigurationProperties不支援強大的SpEL表示式,而Value支援;

四、配置檔案佔位符

佔位符和隨機數比較簡單,這裡就直接貼出程式碼。需要注意的是:

一、佔位符的值必須是完整路徑

二、佔位符設定預設值,冒號後面不能有空格

ran:  # 這裡的prefix不能是random,
  ran-value: ${random.value}
 ran-int: ${random.int}  ran-long: ${random.long}  ran-int-num: ${random.int(10)}  ran-int-range: ${random.int[10,20]}  ran-placeholder: placeholder_${ran.ran-value:此處不能有空格,且key為完整路徑}
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 隨機數和佔位符語法類
 */
@Component
@ConfigurationProperties(prefix = "ran") public class RandomEntity { private String ranValue; // 隨機生成一個字串 private Integer ranInt; // 隨機生成一個整數 private Long ranLong; // 隨機生成一個長整數 private Integer ranIntNum; // 在指定範圍內隨機生成一個整數 private Integer ranIntRange;// 在指定區間內隨機生成一個整數 private String ranPlaceholder;// 佔位符 // 省略getter,setter,toString方法e }

測試程式碼:

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootYmlApplicationTests { @Autowired private UserInfo userInfo; @Autowired private YamlEntity yamlEntity; @Autowired private ConfigurationPropertiesEntity configurationPropertiesEntity; @Autowired private ValueEntity valueEntity; @Autowired private RandomEntity randomEntity; @Test public void contextLoads() { // System.out.println("YAML Grammar : " + yamlEntity); // System.out.println("UserInfo : " + userInfo); // System.out.println("ConfigurationProperties Grammar : " + configurationPropertiesEntity); // System.out.println("Value Grammar : " + valueEntity); System.out.println("Random Grammar : " + randomEntity); } }

五、總結

一、Spring Boot 支援兩種格式的配置檔案,其中YAML的資料結構比properties更清晰。

二、YAML 是專門用來寫配置檔案的語言,非常簡潔和強大。

三、YAML 對空格的要求很嚴格,且不能用Tab鍵代替。

四、YAML 通過空格縮排的程度確定層級,冒號後面有空格,短橫線後面有空格。

五、ConfigurationProperties註解適合批量注入配置檔案中的屬性,Value註解適合獲取配置檔案中的某一項。

六、ConfigurationProperties註解支援資料校驗和獲取複雜的資料,Value註解支援SpEL表示式。

文章到這裡就結束了。如果文章對你有幫助,可以點個"推薦",也可以"關注"我,獲得更多豐富的知識。

這裡是部落格文章目錄一欄表中的部分內容,如果有感興趣的內容可以點選右邊的連結: http://www.cnblogs.com/itdragon/p/8709948.html

文章目錄