Spring Boot 2.4.0.M2 剛剛發(fā)布辱匿,它對 application.properties
和 application.yml
文件的加載方式進行重構。如果應用程序僅使用單個 application.properties
或 application.yml
作為配置文件炫彩,那么可能感受不到任何區(qū)別匾七。但是如果您的應用程序使用更復雜的配置(例如,Spring Cloud 配置中心等)江兢,則需要來了解更改的內容以及原因昨忆。
為什么要進行這些更改
隨著最新版本 Spring Boot 發(fā)布,Spring 一直在努力提升對 Kubernetes 的原生支持杉允。在 Spring Boot 2.3 中邑贴,官方增加 Kubernetes Volume 的配置支持,但是未能實現(xiàn)。
Volume 配置掛載是 Kubernetes 的一項常用功能稠腊,其中 ConfigMap
指令用于直接在文件系統(tǒng)上顯示配置。您可以裝載包含多個鍵和值合并的完整 YAML 文件,也可以使用更簡單的目錄樹格式,其中文件名是鍵糕档,文件內容是值。
希望同時提供兩者的支持,并且能夠兼容我們現(xiàn)有的 application.properties
和 application.yml
吱七。為此需要修改 ConfigFileApplicationListener
類吝岭。
ConfigFileApplicationListener 問題
在 Spring Boot 中配置文件加載類 ConfigFileApplicationListener
屬于比較核心的底層代碼,每次維護都是非常的困難舷丹。并不是因為代碼編寫錯誤或者缺少相關單元測試,而是在添加新功能時,很難解決之前存在的問題诅蝶。
即:
- 配置文件非常靈活舱馅,可以在當前文件啟用其他配置文件缠借。
- 文檔加載順序不固定。
以下面的例子來說:
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文件(一個文件由三個邏輯文檔組成,由 ---
分隔)。
如果使用 --spring.profile.actives=prod
運行屠阻,那么 security.user.password
的值是什么麻诀?是否設置 runlocal
屬性硬毕?中間部分文檔是否包括在內,因為配置文件在處理時沒有激活?
我們經常會遇到關于這個文件處理邏輯的問題,但是每當試圖修復它們時融柬,最后帶來各種各樣的負面問題外盯。
因此狼渊,在 Spring boot 2.4 中對 Properties 和 YAML 文件的加載方式進行兩個重大更改:
- 文檔將按定義的順序加載糕伐。
- profiles 激活開關不能被配置在特定環(huán)境中莺褒。
文檔排序
從 Spring Boot 2.4 開始巡通,加載 Properties 和 YAML 文件時候會遵循弥锄, 在文檔中聲明排序靠前的屬性將被靠后的屬性覆蓋 熬荆。
這點與 .properties
的排序規(guī)則相同。我們可以想一想主巍,每次將一個 Value 放入 Map
散怖,具有相同 key 的新值放入時,將替換已經存在的 Value圈驼。
同理對 Multi-document 的 YAML 文件害碾,較低的排序也將被較高的覆蓋:
test: "value"
---
test: "overridden-value"
Properties
文件支持多文檔屬性
在 Spring Boot 2.4 中, Properties
支持類似 YAML 多文檔功能捎谨。多文檔屬性文件使用注釋( #
)后跟三個(---)破折號來分隔文檔( 選擇使用注釋,以使現(xiàn)有的 IDE 正常支持 )摊灭。
例如根欧,上面的 YAML 等效的 properties 為:
test=value
#---
test=overridden-value
特定環(huán)境激活配置
上述示例實際上沒有任何意義,在我們開發(fā)過程中更為常見是聲明某個屬性僅在特定環(huán)境生效激活呆躲。
在 Spring Boot 2.3 中可以配置 spring.profiles
來實現(xiàn)。但在 Spring Boot 2.4 中 屬性更改 為 spring.config.activate.on-profile
夏块。
例如,我們想要 test
屬性僅僅在 dev
Profile 激活時覆蓋它印蓖,則可以使用以下配置:
test=value
#---
spring.config.activate.on-profile=dev
test=overridden-value
Profile Activation
使用 spring.profiles.active
屬性在 application.properties
或 application.yaml
文件的 根配置文件 來激 相關環(huán)境文件厅各。
例如,下面這樣:
test=value
spring.profiles.active=local
#---
spring.config.activate.on-profile=dev
test=overridden value
不允許的是將 spring.profiles.active
屬性與 spring.config.activate.on-profile
一起使用涝桅。例如批狱,以下文件將引發(fā)異常:
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
Profile Groups 是 Spring Boot 2.4 中的一項新功能疆栏,可讓您將單個配置文件擴展為多個子配置文件调衰。例如,假設有一組復雜的 @Configuration
類竹勉,可以使用 @Profile
注釋有條件地啟用它們。使用 @Profile("proddb")
開啟數(shù)據(jù)庫配置,使用 @Profile("prodmq")
開啟消息配置等等软吐。
使用多個配置文件可以使我們的代碼更易于理解姿现,但是對于部署而言并不是理想的選擇意述。若用戶需要同時激活 proddb
荤崇, prodmq
务唐, prodmetrics
等刑巧。那么 Profile Groups 可讓您做到這一點颜价。
您可以在 application.properties
或 application.yml
文件中定義 spring.profiles.group速侈,那么開啟 prod 則就相當于激活了此組的全部環(huán)境
。例如:
spring.profiles.group.prod=proddb,prodmq,prodmetrics
Importing 擴展 Configuration
現(xiàn)在迫卢,我們已經解決了配置文件處理的基本問題倚搬,我們終于能夠考慮我們想要提供的新功能。我們使用 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
文件篡九,以便團隊中的任何開發(fā)人員都可以快速更改屬性:
application.name=myapp
spring.config.import=developer.properties
甚至可以將 spring.config.import
與 spring.config.activate.on-profile
結合起來使用。例如醋奠,這里 prod.properties
僅在 prod
配置文件處于激活狀態(tài)時加載:
spring.config.activate.on-profile=prod
spring.config.import=prod.properties
Import 可以被視為在聲明它們的文檔下方插入的其他文檔榛臼。它們 遵循與常規(guī)多文檔文件相同的自上而下的順序:導入僅被導入一次,無論聲明了多少次窜司。
volume 掛載配置
導入定義使用與 URL 一樣語法作為其值沛善。如果您的位置沒有前綴,則它被視為常規(guī)文件或文件夾塞祈。但是金刁,如果您使用 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
的內容。
根據(jù)云平臺類型激活
如果只希望 Volume 掛載的配置(或該內容的任何屬性)在特 定的云平臺上 處于激活狀態(tài)哼御,可以使用 spring.config.activate.on-cloud-platform
屬性坯临。它的工作方式與 spring.config.activate.on-profile
類似,但它使用 CloudPlatform
的值恋昼,而不是配置文件名稱尿扯。
如果我們想要在部署到 Kubernetes 時啟用上述配置樹,我們可以執(zhí)行以下操作:
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
屬性即可,恢復到之前版本的文件處理機制缩挑。
如果發(fā)現(xiàn)關于此處的問題但两,則需要切換到舊版處理,請 在 GitHub 上提出問題供置,官方將嘗試解決該問題谨湘。
總結
官方希望新的配置數(shù)據(jù)處理更加好用,并且不會引起太多升級麻煩芥丧。如果您想了解更多有關它們的信息紧阔,可以查閱更新的 參考文檔。
歡迎關注我续担,后續(xù)會通過代碼來詳細說明此處變更擅耽。
翻譯: 冷冷、如夢技術
原文鏈接:https://spring.io/blog/2020/08/14/config-file-processing-in-spring-boot-2-4