Spring Boot 2.4.0.M2 剛剛發佈,它對 application.properties
和 application.yml
文件的加載方式進行重構。若是應用程序僅使用單個 application.properties
或 application.yml
做爲配置文件,那麼可能感覺不到任何區別。可是若是您的應用程序使用更復雜的配置(例如,Spring Cloud 配置中心等),則須要來了解更改的內容以及緣由。html
隨着最新版本 Spring Boot 發佈,Spring 一直在努力提高對 Kubernetes 的原生支持。在 Spring Boot 2.3 中,官方想增長 Kubernetes Volume 的配置支持可是未能實現。java
Volume 配置掛載是 Kubernetes 的一項經常使用功能,其中 ConfigMap
指令用於直接在文件系統上顯示配置。您能夠裝載包含多個鍵和值合併的完整 YAML 文件,也可使用更簡單的目錄樹格式,其中文件名是鍵,文件內容是值。git
但願同時提供二者的支持,而且可以兼容咱們現有的 application.properties
和 application.yml
。爲此須要修改 ConfigFileApplicationListener
類。github
在 Spring Boot 中配置文件加載類 ConfigFileApplicationListener
屬於比較核心的底層代碼,每次維護都是很是的困難。並非由於代碼編寫錯誤或者缺乏相關單元測試,而是在添加新功能時,很難解決以前存在的問題。spring
即:數據庫
如下面的例子來講:markdown
security.user.password: usera
---
spring.profiles: local
security.user.password: userb
runlocal: true
---
spring.profiles: !dev
spring.profiles.include: local
security.user.password: userc
複製代碼
在這裏,咱們有一個 多文檔 YAML文件(一個文件由三個邏輯文檔組成,由 ---
分隔)。app
若是使用 --spring.profile.actives=prod
運行,那麼 security.user.password
的值是什麼?是否設置 runlocal
屬性?中間部分文檔是否包括在內,由於配置文件在處理時沒有激活?spring-boot
咱們常常會遇到關於這個文件處理邏輯的問題,可是每當試圖修復它們時,最後帶來各類各樣的負面問題。oop
所以,在 Spring boot 2.4 中對 Properties 和 YAML 文件的加載方式進行兩個重大更改:
從 Spring Boot 2.4 開始,加載 Properties 和 YAML 文件時候會遵循, 在文檔中聲明排序靠前的屬性將被靠後的屬性覆蓋 。
這點與 .properties
的排序規則相同。咱們能夠想想,每次將一個 Value 放入 Map
,具備相同 key 的新值放入時,將替換已經存在的 Value。
同理對 Multi-document 的 YAML 文件,較低的排序也將被較高的覆蓋:
test: "value"
---
test: "overridden-value"
複製代碼
Properties
文件支持多文檔屬性在 Spring Boot 2.4 中, Properties
支持相似 YAML 多文檔功能。多文檔屬性文件使用註釋( #
)後跟三個(---)破折號來分隔文檔( 選擇使用註釋,以使現有的 IDE 正常支持 )。
例如,上面的 YAML 等效的 properties 爲:
test=value
#---
test=overridden-value
複製代碼
上述示例實際上沒有任何意義,在咱們開發過程當中更爲常見是聲明某個屬性僅在特定環境生效激活。
在 Spring Boot 2.3 中能夠配置 spring.profiles
來實現。但在 Spring Boot 2.4 中 屬性更改 爲 spring.config.activate.on-profile
。
例如,咱們想要 test
屬性僅僅在 dev
Profile 激活時覆蓋它,則可使用如下配置:
test=value
#---
spring.config.activate.on-profile=dev
test=overridden-value
複製代碼
使用 spring.profiles.active
屬性在 application.properties
或 application.yaml
文件的 根配置文件 來激 相關環境文件。
例如,下面這樣:
test=value
spring.profiles.active=local
#---
spring.config.activate.on-profile=dev
test=overridden value
複製代碼
不容許的是將 spring.profiles.active
屬性與 spring.config.activate.on-profile
一塊兒使用。例如,如下文件將引起異常:
test=value
#---
spring.config.activate.on-profile=dev
spring.profiles.active=local # will fail
test=overridden value
複製代碼
經過這一新限制能使 application.properties
和 application.yml
文件更加容易理解。使得 Spring Boot 自己更易於管理和維護。
Profile Groups 是 Spring Boot 2.4 中的一項新功能,可以讓您將單個配置文件擴展爲多個子配置文件。例如,假設有一組複雜的 @Configuration
類,可使用 @Profile
註釋有條件地啓用它們。使用 @Profile("proddb")
開啓數據庫配置,使用 @Profile("prodmq")
開啓消息配置等等。
使用多個配置文件可使咱們的代碼更易於理解,可是對於部署而言並非理想的選擇。若用戶須要同時激活 proddb
, prodmq
, prodmetrics
等。那麼 Profile Groups 可以讓您作到這一點。
您能夠在 application.properties
或 application.yml
文件中定義 spring.profiles.group,那麼開啓 prod 則就至關於激活了此組的所有環境
。例如:
spring.profiles.group.prod=proddb,prodmq,prodmetrics
複製代碼
如今,咱們已經解決了配置文件處理的基本問題,咱們終於可以考慮咱們想要提供的新功能。咱們使用 Spring Boot 2.4 提供的主要功能是支持導入其餘配置。
對於早期版本的 Spring Boot,很難在 application.properties
和 application.yml
以外導入其餘 properties
或 yaml
文件。可使用 spring.config.additional-location
屬性但它能夠處理的文件類型很是有限。
在 Spring Boot 2.4 能夠直接在 application.properties
或 application.yml
文件中使用新的 spring.config.import
屬性。例如但願導入一個 "忽略的 git" 的 developer.properties
文件,以便團隊中的任何開發人員均可以快速更改屬性:
application.name=myapp
spring.config.import=developer.properties
複製代碼
甚至能夠將 spring.config.import
與 spring.config.activate.on-profile
結合起來使用。例如,這裏 prod.properties
僅在 prod
配置文件處於激活狀態時加載:
spring.config.activate.on-profile=prod
spring.config.import=prod.properties
複製代碼
Import 能夠被視爲在聲明它們的文檔下方插入的其餘文檔。它們 遵循與常規多文檔文件相同的自上而下的順序:導入僅被導入一次,不管聲明瞭多少次。
導入定義使用與 URL 同樣語法做爲其值。若是您的位置沒有前綴,則它被視爲常規文件或文件夾。可是,若是您使用 configtree:
前綴,則告訴 Spring Boot,您將指望在該位置使用 Kubernetes volume 裝載的配置樹。
例如,您能夠在 application.properties
配置:
spring.config.import=configtree:/etc/config
複製代碼
若是您有如下裝載的內容:
etc/
+- config/
+- my/
| +- application
+- test
複製代碼
將在 Spring Environment
中擁有 my.application
和 test
屬性。 my.application
的值是 /etc/config/my/application
的內容, test
的值是 /etc/config/test
的內容。
若是隻但願 Volume 掛載的配置(或該內容的任何屬性)在特 定的雲平臺上 處於激活狀態,可使用 spring.config.activate.on-cloud-platform
屬性。它的工做方式與 spring.config.activate.on-profile
相似,但它使用 CloudPlatform
的值,而不是配置文件名稱。
若是咱們想要在部署到 Kubernetes 時啓用上述配置樹,咱們能夠執行如下操做:
spring.config.activate.on-cloud-platform=kubernetes
spring.config.import=configtree:/etc/config
複製代碼
spring.config.import
屬性中指定的位置字符串是徹底可插拔的,能夠經過編寫幾個自定義類來擴展,第三方庫將對自定義位置提供支持。例如,你能想到的第三方 jar 文件,例如 archaius://…
, vault://…
或 zookeeper://…
。
若是您有興趣添加其餘位置支持,請查看 org.springframework.boot.context.config
包 ConfigDataLocationResolver
和 ConfigDataLoader
的 javadoc。
正如上文所描述的,Spring Boot 針對配置文件的功能變動是很是大的。考慮到低版本的兼容性
能夠設置 spring.config.use-legacy-processing=true
屬性便可,恢復到以前版本的文件處理機制。
若是發現關於此處的問題,則須要切換到舊版處理,請 在 GitHub 上提出問題,官方將嘗試解決該問題。
官方但願新的配置數據處理更加好用,而且不會引發太多升級麻煩。若是您想了解更多有關它們的信息,能夠查閱更新的 參考文檔。
歡迎關注我,後續會經過代碼來詳細說明此處變動。
翻譯: 冷冷、如夢技術