Springboot配置管理Externalized?Configuration深入探究
Springboot通過Externalized Configuration
通過配置文件提高代碼靈活性是每一個應(yīng)用都必然要考慮的現(xiàn)實問題,Springboot通過Externalized Configuration(外部化配置)對配置文件提供了非常靈活的支持。
Spring Boot lets you externalize your configuration so that you can work with the same application code in different environments. You can use a variety of external configuration sources including Java properties files, YAML files, environment variables, and command-line arguments.
Spring Boot允許你外部化配置文件,因此你可以讓相同的代碼在不同的環(huán)境下工作。你可以采用包括Java properties files、YAML files、環(huán)境變量、命令行參數(shù)等在內(nèi)的多種外部化方式進行配置。
Spring Boot提供的多種外部配置優(yōu)先級
Spring Boot提供的多種外部配置優(yōu)先級如下(從低到高),優(yōu)先級高的配置項會覆蓋掉優(yōu)先級低的配置項而最終生效:
- Default properties: 通過SpringApplication.setDefaultProperties設(shè)置。
- @PropertySource注解:在@Configuration注解文件中使用,這種方式的配置文件在applicatio context刷新的時候生效。因此對于需要在容器刷新前就生效的某些配置項比如logging. and spring.main. ,此種方式的配置不會生效。
- Config data:比如application.properties配置文件等。
- 隨機數(shù)配置器:A RandomValuePropertySource that has properties only in random.*。
- OS environment variables:操作系統(tǒng)環(huán)境變量。
- Java System properties :Java系統(tǒng)屬性,通過System.getProperties()獲取。
- JNDI attributes from java:comp/env。
- ServletContext init parameters。
- ServletConfig init parameters。
- Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property),通過環(huán)境變量或系統(tǒng)屬性配置的JSON方式的配置信息。
- Command line arguments:命令行參數(shù)。
- properties attribute on your tests. Available on @SpringBootTest and the test annotations for testing a particular slice of your application。
- @DynamicPropertySource annotations in your tests。
- @TestPropertySource annotations on your tests。
- Devtools global settings properties in the $HOME/.config/spring-boot directory when devtools is active。
其中第3項中的Config data files的優(yōu)先級(從低到高):
- Application properties packaged inside your jar (application.properties and YAML variants):jar包內(nèi)的properties或yaml配置文件。
- Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants):jar包內(nèi)的profile標(biāo)識的properties或yaml配置文件。
- Application properties outside of your packaged jar (application.properties and YAML variants):jar包外的properies或yaml配置文件。
- Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants):jar包外的profile標(biāo)識的properties或yaml配置文件。
It is recommended to stick with one format for your entire application. If you have configuration files with both .properties and YAML format in the same location, .properties takes precedence.
注意:建議你的Spring Boot項目采用同一種配置文件完成配置,如果項目中的同一位置同時存在.properties和.yaml文件,則.properties文件優(yōu)先(yaml配置文件中的相同配置無效)。
命令行參數(shù)
Spring Boot可以讀取命令行參數(shù)到配置屬性中,命令行參數(shù)通過 -- 符號設(shè)置,比如 --server.port=8080。命令行參數(shù)比配置文件具有更高的優(yōu)先級。
通過SpringApplication.setAddCommandLineProperties(false)可以禁用命令行參數(shù)。
JSON Application Properties
以下三種方式設(shè)置:
操作系統(tǒng)環(huán)境變量:
$ SPRING_APPLICATION_JSON='{"my":{"name":"test"}}' java -jar myapp.jar
java 系統(tǒng)屬性:
$ java -Dspring.application.json='{"my":{"name":"test"}}' -jar myapp.jar
通過命令行參數(shù):
$ java -jar myapp.jar --spring.application.json='{"my":{"name":"test"}}'
External Application Properties
Spring Boot啟動過程中從如下路徑自動調(diào)用application.properties或application.yaml文件:
- 從classpath調(diào)用
a. classpath根目錄
b. classpath下的 /config目錄 - 從當(dāng)前目錄調(diào)用
a. 當(dāng)前目錄
b. 當(dāng)前目錄下的 /config目錄
c. /config目錄下的子目錄
以上順序是Spring Boot加載配置文件的優(yōu)先級(由低到高),后面的配置文件會覆蓋掉前面的配置文件。配置文件讀取后會被加載到會被加載的Spring Environment的PropertySources 中。
application是默認(rèn)的配置文件名,可以通過如下方式修改:
$ java -jar myproject.jar --spring.config.name=myproject
也可以通過環(huán)境變量spring.config.location修改,如:
$ java -jar myproject.jar --spring.config.location=\
optional:classpath:/default.properties,\ optional:classpath:/override.properties
optional表示當(dāng)前配置是可選的,指定位置不存在該配置文件,系統(tǒng)也不會報錯。否則不指定optional、配置文件不存在的話,Spring Boot啟動過程中會拋出ConfigDataLocationNotFoundException異常。
全局變量spring.config.on-not-found設(shè)置為ignore,可以讓Spring Boot忽略所有的配置文件不存在異常、繼續(xù)啟動系統(tǒng):
SpringApplication.setDefaultProperties(…) or with a system/environment variable.
spring.config.name, spring.config.location, and spring.config.additional-location等三個參數(shù)在Spring Boot項目啟動的早期就會被調(diào)用,所以,必須通過環(huán)境屬性指定、而不能通過配置文件的方式指定。
spring.config.location支持profile。
Wildcard Locations
帶 的配置文件位置的含義是:Spring Boot讀取配置文件的時候,指定位置的子目錄也被包含在內(nèi)。對于有多個配置文件的應(yīng)用, 配置方式會比較方便。
默認(rèn)情況下,Spring Boot會包含 config/*/ 作為其默認(rèn)的配置文件搜索路徑。意思是jar包下的config路徑及其子目錄下的配置文件都會生效。
可以在spring.config.location或spring.config.additional-location參數(shù)中使用 * 指定配置文件。
Profile Specific Files
這一特性主要是為了支持應(yīng)用在多個環(huán)境下采用不同配置參數(shù)的場景,比如開發(fā)環(huán)境、測試環(huán)境、生產(chǎn)環(huán)境,同一參數(shù)在這三個不同的環(huán)境下的參數(shù)配置不同,如果在系統(tǒng)部署的時候手工切換(相信之前有好多項目確實就是這么干的),很有可能會由于操作失誤導(dǎo)致嚴(yán)重問題。
Spring Boot官網(wǎng)描述的很清楚:
Profile-specific properties are loaded from the same locations as standard application.properties, with profile-specific files always overriding the non-specific ones. If several profiles are specified, a last-wins strategy applies. For example, if profiles prod,live are specified by the spring.profiles.active property, values in application-prod.properties can be overridden by those in application-live.properties.
通過spring.profiles.active參數(shù)指定profile后,相同位置存在多個相同配置文件(名字相同、profile不同)的情況下,指定的profile文件會生效。比如,spring.profiles.active指定為prod,live,當(dāng)前路徑下如果同時存在application.yml、application-prod.yml、application-live.yml,那么,如果三個配置文件中都存在同一項配置,則application-live.yml中的配置勝出(會生效)。
以下描述了“后來者勝出”策略的生效方式,通過spring.config.location參數(shù)指定配置文件位置的情況下,有“同一配置組”和“不同配置組”的區(qū)別:
The last-wins strategy applies at the location group level. A spring.config.location of classpath:/cfg/,classpath:/ext/ will not have the same override rules as classpath:/cfg/;classpath:/ext/.
For example, continuing our prod,live example above, we might have the following files:
/cfg
application-live.properties
/ext
application-live.properties
application-prod.properties
When we have a spring.config.location of classpath:/cfg/,classpath:/ext/ we process all /cfg files before all /ext files:/cfg/application-live.properties
/ext/application-prod.properties
/ext/application-live.properties
When we have classpath:/cfg/;classpath:/ext/ instead (with a ; delimiter) we process /cfg and /ext at the same level:
1./ext/application-prod.properties
2./cfg/application-live.properties
3./ext/application-live.properties
建議盡可能用最簡單的方式進行配置:指定profile的情況下,盡可能不將同一類型的(比如某一三方API連接參數(shù))、不同環(huán)境(比如測試、開發(fā)、生產(chǎn))的配置文件放置在不同的路徑下,以免引起誤傷!
Importing Additional Data
Spring Boot支持通過spring.config.import定義配置文件路徑,Spring Boot啟動過程中從指定路徑導(dǎo)入配置內(nèi)容。
比如在application.properties文件中指定:
spring.application.name=myapp
spring.config.import=optional:file:./dev.properties
則當(dāng)前路徑下如果存在dev.properties文件的話,Spring Boot會導(dǎo)入該文件的配置內(nèi)容。并且,dev.properties配置文件中的內(nèi)容優(yōu)先級高于定義他的文件(上例中的application.properties)。以上案例中如果dev.properties文件中存在spring.application.name,會覆蓋掉application.properties文件中的值myapp。
以上案例中,Spring Boot會首先讀取application.properties文件中的配置內(nèi)容,之后讀取dev.properties文件中的配置內(nèi)容并覆蓋掉application.properties文件中的相同配置內(nèi)容。因此,application.properties文件中spring.config.import的定義位置無關(guān)緊要,不管放在spring.application.name的前面、還是后面,都會覆蓋掉application.properties文件中的spring.application.name值。
spring.config.import配置支持profile。
Importing Extensionless Files
有些應(yīng)用的配置文件沒有擴展名,Spring Boot可以通過 [ ] 支持導(dǎo)入。
比如配置文件是/etc/config/myconfig,文件格式是yaml,則可以配置為:
spring.config.import=file:/etc/config/myconfig[.yaml]
Using Configuration Trees
通過configtree關(guān)鍵字,指定路徑下的文件名作為key、文件內(nèi)容作為values導(dǎo)入Spring Boot Environment的properties中。
比如:
spring.config.import=optional:configtree:/etc/config/
/etc/config/myapp路徑下有username和password兩個文件:
etc/
config/
myapp/ username password
則myapp.username和myapp.password 將會注入到Environment的properties中。
Property Placeholders
參數(shù)可以通過占位符配置,比如:
app.name=MyApp
app.description=${app.name} is a Spring Boot application written by ${username:Unknown}
占位符app.name會被MyApp替代,如果系統(tǒng)中沒有username這個配置值的話,系統(tǒng)會以冒號 : 后的值Unknown作為默認(rèn)值。
Working With Multi-Document Files
Spring Boot支持將同一個物理文件在邏輯上拆分成多個文件來處理。
比如,yaml文件,三個短橫線 --- 表示邏輯上一個配置文件的結(jié)束、另外一個配置文件的開始:
spring: application: name: "MyApp" --- spring: application: name: "MyCloudApp" config: activate: on-cloud-platform: "kubernetes"
properties文件,#--- 或者 !--- 表示邏輯上一個配置文件的結(jié)束、另外一個配置文件的開始:
spring.application.name=MyApp #--- spring.application.name=MyCloudApp spring.config.activate.on-cloud-platform=kubernetes
后面的配置文件內(nèi)容將會覆蓋掉前面配置文件的,上述案例的spring.application.name取值為MyCloudApp。
Activation Properties
通過spring.config.activate.*參數(shù)設(shè)置配置文件的內(nèi)容僅在指定的激活條件下生效,Spring Boot支持如下激活條件:
- on-profile:僅針對指定的profile生效。
- on-cloud-platform:僅針對指定的云平臺參數(shù)生效。
比如:
myprop=always-set #--- spring.config.activate.on-cloud-platform=kubernetes spring.config.activate.on-profile=prod | staging myotherprop=sometimes-set
---下面的(第二個邏輯文件內(nèi)容)僅針對云平臺kubernetes、以及profile為 prod或者staging生效。
Working With YAML
YAML格式的配置文件需要SnakeYAML包的支持,spring-boot-starter自動包含了SnakeYAML包,所以Spring Boot項目是默認(rèn)支持YAML配置文件的。
Type-safe Configuration Properties
Spring Boot提供兩種不同的配置參數(shù)綁定方式,一種是通過@Value注解,另外一種是Type-safe Configuration Properties:
@Value注解使用起來比較方便,但是個人認(rèn)為不利于代碼管理,因為配置參數(shù)的綁定會分散在代碼各處。
- 綁定到JavaBean屬性:通過@ConfigurationProperties("my.service")注解直接綁定打JavaBean的屬性上。
- 通過構(gòu)造器綁定:通過@ConfigurationProperties("my.service")注解、構(gòu)造器參數(shù)完成綁定。
- 通過@EnableConfigurationProperties(SomeProperties.class)注解、指定特定的java類完成綁定。
- 通過@ConfigurationPropertiesScan注解,采用配置文件屬性掃描的方式完成綁定(類似于IoC容器注入bean是的組件掃描機制)。
- 通過@Configuration、 @ConfigurationProperties以及@Bean結(jié)合的方式完成綁定。
Relaxed Binding
Spring Boot的Relaxed Binding- 寬松綁定看,指的是SpringBoot在綁定配置文件參數(shù)的java配置類的屬性上的時候,提供一種寬松的匹配規(guī)則,在配置文件中的配置和javabean中的屬性名稱不是完全一一對應(yīng)的情況下,也可以實現(xiàn)屬性綁定。
比如:
@ConfigurationProperties(prefix = "my.main-project.person") public class MyPersonProperties { private String firstName; public String getFirstName() { return this.firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } }
在寬松綁定規(guī)則下,如下配置均可綁定:
Spring Boot官網(wǎng)指定的寬松綁定規(guī)則:
以上,關(guān)于Sprng Boot配置文件的內(nèi)容絕大部分來之與Spring Boot官網(wǎng),Spring Boot提供了非常強大、靈活的配置文件綁定方式,但是建議大家在實際項目中采用最基礎(chǔ)的、最簡單的方式進行配置,不沖突、無歧義、能實現(xiàn)目標(biāo)的前提條件下,越簡單越好,更多關(guān)于Springboot Externalized Configuration的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java集合之Comparable和Comparator接口詳解
Java提供了Comparable接口與Comparator接口,它們?yōu)閿?shù)組或集合中的元素提供了排序邏輯,實現(xiàn)此接口的對象數(shù)組或集合可以通過Arrays.sort或Collections.sort進行自動排序。本文將通過示例講講它們的使用,需要的可以參考一下2022-12-12SpringBoot整合Redis實現(xiàn)附近位置查找(LBS)功能
Redis 提供了 GEO 數(shù)據(jù)結(jié)構(gòu),可以高效地存儲和查詢地理位置數(shù)據(jù),本文將介紹如何使用 Spring Boot + Redis 來實現(xiàn)附近位置查找,需要的可以了解下2025-03-03IDEA調(diào)試源碼小技巧之辨別抽象類或接口多種實現(xiàn)類的正確路徑
這篇文章主要介紹了IDEA調(diào)試源碼小技巧之辨別抽象類或接口多種實現(xiàn)類的正確路徑,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-01-01IDEA項目中配置Maven鏡像源(下載源)的詳細(xì)過程
Maven是一個能使我們的java程序開發(fā)節(jié)省時間和精力,是開發(fā)變得相對簡單,還能使開發(fā)規(guī)范化的工具,下面這篇文章主要給大家介紹了關(guān)于IDEA項目中配置Maven鏡像源(下載源)的詳細(xì)過程,需要的朋友可以參考下2024-02-02ShardingSphere數(shù)據(jù)庫讀寫分離算法及測試示例詳解
這篇文章主要為大家介紹了ShardingSphere數(shù)據(jù)庫讀寫分離算法及測試示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-03-03