Spring Boot 2.4.0.M2 剛剛釋出 ,它對 application.properties application.yml application.properties application.yml
和
檔案的加載方式進行重構。如果應用程式僅使用單個
或
作為配置檔案,那麼可能感受不到任何差別。但是如果您的應用程式使用更複雜的配置(例如,Spring Cloud 配置中心等),則需要來了解更改的内容以及原因。
為什麼要進行這些更改
随着最新版本 Spring Boot 釋出,Spring 一直在努力提升對 Kubernetes 的原生支援。在 Spring Boot 2.3 中,官方增加 Kubernetes Volume 的配置支援,但是未能實作。
Volume 配置挂載是 Kubernetes 的一項常用功能,其中
ConfigMap
指令用于直接在檔案系統上顯示配置。您可以裝載包含多個鍵和值合并的完整 YAML 檔案,也可以使用更簡單的目錄樹格式,其中檔案名是鍵,檔案内容是值。
希望同時提供兩者的支援,并且能夠相容我們現有的
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 激活開關不能被配置在特定環境中。
文檔排序
從 Spring Boot 2.4 開始,加載 Properties 和 YAML 檔案時候會遵循, 在文檔中聲明排序靠前的屬性将被靠後的屬性覆寫 。
這點與
.properties
的排序規則相同。我們可以想一想,每次将一個 Value 放入
Map
,具有相同 key 的新值放入時,将替換已經存在的 Value。
同理對 Multi-document 的 YAML 檔案,較低的排序也将被較高的覆寫:
test: "value"
---
test: "overridden-value"
Properties
檔案支援多文檔屬性
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
Profile Activation
使用
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
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
Importing 擴充 Configuration
現在,我們已經解決了配置檔案處理的基本問題,我們終于能夠考慮我們想要提供的新功能。我們使用 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 可以被視為在聲明它們的文檔下方插入的其他文檔。它們 遵循與正常多文檔檔案相同的自上而下的順序:導入僅被導入一次,無論聲明了多少次。
volume 挂載配置
導入定義使用與 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 上提出問題,官方将嘗試解決該問題。
總結
官方希望新的配置資料處理更加好用,并且不會引起太多更新麻煩。如果您想了解更多有關它們的資訊,可以查閱更新的
參考文檔歡迎關注我,後續會通過代碼來詳細說明此處變更。
翻譯: 冷冷、如夢技術
原文連結:
https://spring.io/blog/2020/08/14/config-file-processing-in-spring-boot-2-4項目推薦: Spring Cloud 、Spring Security OAuth2的RBAC權限管理系統 歡迎關注