天天看點

SpringBoot讀取配置檔案的幾種方式

Spring讀取配置檔案的幾種方法,SpringBoot也都支援。具體檢視: ​

本文主要介紹SpringBoot獨有的一種讀取方法,使用注解:@ConfigurationProperties。

使用 @Value 注解或者使用 Spring Environment bean 通路這些屬性,是這種注入配置方式有時顯得很笨重。使用@ConfigurationProperties )來擷取這些屬性會更靈活。

@ConfigurationProperties 的基本用法非常簡單:為每個要捕獲的外部屬性提供一個帶有字段的類。請注意以下幾點:

字首定義了哪些外部屬性将綁定到類的字段上

根據 Spring Boot 寬松的綁定規則,類的屬性名稱必須與外部屬性的名稱比對

我們可以簡單地用一個值初始化一個字段來定義一個預設值

類本身可以是包私有的

類的字段必須有公共 setter 方法

Spring 寬松綁定規則 (relaxed binding) Spring使用一些寬松的綁定屬性規則。是以,以下變體都将綁定到 hostName 屬性上: mail.hostName=localhost mail.hostname=localhost mail.host_name=localhost mail.host-name=localhost mail.HOST_NAME=localhost

添加@Component等注元件注解

通過 Spring 的 Java Configuration 特性實作(@Bena)。

使用@EnableConfigurationProperties 注解

該注解中其實是用了@Import(EnableConfigurationPropertiesImportSelector.class) 實作(不推薦)。

如果我們在 application.properties 屬性上定義的屬性不能被正确的解析會發生什麼?預設情況下,Spring Boot 将會啟動失敗,并抛出異常。

當我們為屬性配置錯誤的值時,而又不希望 Spring Boot 應用啟動失敗,我們可以設定 ignoreInvalidFields 屬性為 true (預設為 false)。

如果我們在 application.properties 檔案提供了 MailModuleProperties 類不知道的屬性會發生什麼?

預設情況下,Spring Boot 會忽略那些不能綁定到 @ConfigurationProperties 類字段的屬性。

然而,當配置檔案中有一個屬性實際上沒有綁定到 @ConfigurationProperties 類時,我們可能希望啟動失敗。也許我們以前使用過這個配置屬性,但是它已經被删除了,這種情況我們希望被觸發告知手動從 application.properties 删除這個屬性。

為了實作上述情況,我們僅需要将 ignoreUnknownFields 屬性設定為 false (預設是 true)。

棄用警告⚠️(Deprecation Warning) ignoreUnknownFields 在未來 Spring Boot 的版本中會被标記為 deprecated,因為我們可能有兩個帶有 @ConfigurationProperties 的類,同時綁定到了同一個命名空間 (namespace) 上,其中一個類可能知道某個屬性,另一個類卻不知道某個屬性,這樣就會導緻啟動失敗

 如果我們希望配置參數在傳入到應用中時有效的,我們可以通過在字段上添加 bean validation 注解,同時在類上添加 @Validated 注解。

應用啟動時,我們将會得到 BindValidationException。

當然這些預設的驗證注解不能滿足你的驗證要求,我們也可以自定義注解。

如果你的驗證邏輯很特殊,我們可以實作一個方法,并用 @PostConstruct 标記,如果驗證失敗,方法抛出異常即可。

多數情況,我們傳遞給應用的參數是基本的字元串或數字。但是,有時我們需要傳遞諸如 List 的資料類型。

SpringBoot讀取配置檔案的幾種方式

我們有兩種方式讓 Spring Boot 自動填充該 list 屬性。

(1) application.properties

在 application.properties 檔案中以數組形式書寫:

SpringBoot讀取配置檔案的幾種方式

(2) application.yml

YAML 本身支援 list 類型,是以可以在 application.yml 檔案中添加:

SpringBoot讀取配置檔案的幾種方式

set 集合也是這種方式的配置方式,不再重複書寫。另外YAML 是更好的閱讀方式,層次分明,是以在實際應用中更推薦大家使用該種方式做資料配置。

SpringBoot也支援Map<String,String>的讀取。

1、application.properties配置如下:

注意:如果Map類型的key包含非字母數字和-的字元,需要用[]括起來,否則不需要使用中括号。

2、配置類讀取如下:

3、擴充:使用@Value的方式擷取

要使用@Value的方式擷取,首先配置檔案中,配置的方式要改下,如下:

注意:如果Map類型的key包含非字母數字和-的字元,需要用引号括起來,否則不需要使用引号(建議都用上引号);value值,都必須要用引号括起來。

在使用該配置的地方,使用@Value的使用擷取:

Spring Boot 内置支援從配置參數中解析 durations (持續時間)。

SpringBoot讀取配置檔案的幾種方式

我們既可以配置毫秒數數值,也可配置帶有機關的文本。

SpringBoot讀取配置檔案的幾種方式

配置 duration 不寫機關,預設按照毫秒來指定,我們也可已認證 @DurationUnit 來指定機關。

SpringBoot讀取配置檔案的幾種方式

常用機關如下:

​<code>​ns​</code>​ for nanoseconds (納秒)

​<code>​us​</code>​ for microseconds (微秒)

​<code>​ms​</code>​ for milliseconds (毫秒)

​<code>​s​</code>​ for seconds (秒)

​<code>​m​</code>​ for minutes (分)

​<code>​h​</code>​ for hours (時)

​<code>​d​</code>​ for days (天)

與 Duration 的用法一樣,預設機關是 byte (位元組),可以通過 @DataSizeUnit 機關指定。

SpringBoot讀取配置檔案的幾種方式

添加配置

SpringBoot讀取配置檔案的幾種方式

但是,我測試的時候列印出來結果都是以 B (bytes) 來顯示

常見機關如下:

​<code>​B​</code>​ for bytes

​<code>​KB​</code>​ for kilobytes

​<code>​MB​</code>​ for megabytes

​<code>​GB​</code>​ for gigabytes

​<code>​TB​</code>​ for terabytes

有些情況,我們想解析配置參數到我們自定義的對象類型上,假設,我們我們設定最大包裹重量:

SpringBoot讀取配置檔案的幾種方式

在 MailModuleProperties 中添加 Weight 屬性

SpringBoot讀取配置檔案的幾種方式

我們可以模仿 DataSize 和 Duration 創造自己的 converter (轉換器)

SpringBoot讀取配置檔案的幾種方式

将其注冊到 Spring Boot 上下文中

SpringBoot讀取配置檔案的幾種方式

@ConfigurationPropertiesBinding 注解是讓 Spring Boot 知道使用該轉換器做資料綁定。

添加依賴:

SpringBoot讀取配置檔案的幾種方式

重新 build 項目之後,configuration processor 會為我們建立一個 JSON 檔案:

這樣,當我們在 application.properties 和 application.yml 中寫配置的時候會有自動提醒。

SpringBoot讀取配置檔案的幾種方式

configuration processor 允許我們标記某一個屬性為 deprecated

SpringBoot讀取配置檔案的幾種方式

我們可以通過添加 @DeprecatedConfigurationProperty 注解到字段的 getter 方法上,來标示該字段為 deprecated,重新 build 項目,看看 JSON 檔案發生了什麼?

SpringBoot讀取配置檔案的幾種方式

當我們再編寫配置檔案時,已經給出了明确 deprecated 提示:

SpringBoot讀取配置檔案的幾種方式

Spring Boot 的 @ConfigurationProperties 注解在綁定類型安全的 Java Bean 時是非常強大的,我們可以配合其注解屬性和 @DeprecatedConfigurationProperty 注解擷取到更友好的程式設計方式,同時這樣讓我們的配置更加子產品化。

注意:如果使用 SpEL 表達式,我們隻能選擇 @Value 注解。

時刻與技術進步,每天一點滴,日久一大步!!!

本部落格隻為記錄,用于學習,如有冒犯,請私信于我。