SpringBoot讀取配置文件的幾種方式


Spring讀取配置文件的幾種方法,SpringBoot也都支持。具體查看:https://www.cnblogs.com/myitnews/p/14028588.html

本文主要介紹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

一、激活@ConfigurationProperties

  • 添加@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) 上,其中一個類可能知道某個屬性,另一個類卻不知道某個屬性,這樣就會導致啟動失敗

三、啟動時校驗 @ConfigurationProperties

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

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

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

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

四、復雜屬性類型

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

List 和 Set

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

(1) application.properties

在 application.properties 文件中以數組形式書寫:

(2) application.yml

YAML 本身支持 list 類型,所以可以在 application.yml 文件中添加:

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

Map<String, String>

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

1、application.properties配置如下:

fyk.db-script.check-sql.[1-FYK_PROPERTIES-DQL]=select case when exists(select 1 from all_tables t where t.TABLE_NAME = upper('fyk_properties')) then 1 else 0 end as result from dual
fyk.db-script.check-sql.[2-FYK_PROPERTIES-DML-fyk-oauth]=select case when exists(select 1 from fyk_properties t where t.application='fyk-oauth') then 1 else 0 end as result from dual

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

2、配置類讀取如下:

@Component
@ConfigurationProperties(prefix = "fyk.db-script")
public class CheckSqlProperties {
    private Map<String, String> checkSql;

    public Map<String, String> getCheckSql() {
        return checkSql;
    }

    public void setCheckSql(Map<String, String> checkSql) {
        this.checkSql = checkSql;
    }
}

3、擴展:使用@Value的方式獲取

要使用@Value的方式獲取,首先配置文件中,配置的方式要改下,如下:

fyk.db-script.check-sql={\
  "1-FYK_PROPERTIES-DQL":"select case when exists(select 1 from all_tables t where t.TABLE_NAME = upper('fyk_properties')) then 1 else 0 end as result from dual",\
  "2-FYK_PROPERTIES-DML-fyk-oauth":"select case when exists(select 1 from fyk_properties t where t.application='fyk-oauth') then 1 else 0 end as result from dual"\
  }

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

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

@Value("#{${fyk.db-script.check-sql}}")
private Map<String, String> checkSql
Duration

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

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

配置 duration 不寫單位,默認按照毫秒來指定,我們也可已通過 @DurationUnit 來指定單位。

常用單位如下:

  • ns for nanoseconds (納秒)
  • us for microseconds (微秒)
  • ms for milliseconds (毫秒)
  • s for seconds (秒)
  • m for minutes (分)
  • h for hours (時)
  • d for days (天)
DataSize

與 Duration 的用法一樣,默認單位是 byte (字節),可以通過 @DataSizeUnit 單位指定。

添加配置

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

常見單位如下:

  • B for bytes
  • KB for kilobytes
  • MB for megabytes
  • GB for gigabytes
  • TB for terabytes
自定義類型

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

在 MailModuleProperties 中添加 Weight 屬性

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

將其注冊到 Spring Boot 上下文中

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

五、使用 Spring Boot Configuration Processor 完成自動補全

添加依賴:

重新 build 項目之后,configuration processor 會為我們創建一個 JSON 文件:

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

六、標記配置屬性為 Deprecated

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

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

當我們再編寫配置文件時,已經給出了明確 deprecated 提示:

七、總結

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

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

 

轉自:https://www.cnblogs.com/jimoer/p/11374229.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM