Springboot配置管理Externalized?Configuration深入探究
Springboot通過(guò)Externalized Configuration
通過(guò)配置文件提高代碼靈活性是每一個(gè)應(yīng)用都必然要考慮的現(xiàn)實(shí)問(wèn)題,Springboot通過(guò)Externalized Configuration(外部化配置)對(duì)配置文件提供了非常靈活的支持。
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)的多種外部化方式進(jìn)行配置。
Spring Boot提供的多種外部配置優(yōu)先級(jí)
Spring Boot提供的多種外部配置優(yōu)先級(jí)如下(從低到高),優(yōu)先級(jí)高的配置項(xiàng)會(huì)覆蓋掉優(yōu)先級(jí)低的配置項(xiàng)而最終生效:
- Default properties: 通過(guò)SpringApplication.setDefaultProperties設(shè)置。
- @PropertySource注解:在@Configuration注解文件中使用,這種方式的配置文件在applicatio context刷新的時(shí)候生效。因此對(duì)于需要在容器刷新前就生效的某些配置項(xiàng)比如logging. and spring.main. ,此種方式的配置不會(huì)生效。
- Config data:比如application.properties配置文件等。
- 隨機(jī)數(shù)配置器:A RandomValuePropertySource that has properties only in random.*。
- OS environment variables:操作系統(tǒng)環(huán)境變量。
- Java System properties :Java系統(tǒng)屬性,通過(guò)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),通過(guò)環(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項(xiàng)中的Config data files的優(yōu)先級(jí)(從低到高):
- 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)識(shí)的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)識(shí)的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項(xiàng)目采用同一種配置文件完成配置,如果項(xiàng)目中的同一位置同時(shí)存在.properties和.yaml文件,則.properties文件優(yōu)先(yaml配置文件中的相同配置無(wú)效)。
命令行參數(shù)
Spring Boot可以讀取命令行參數(shù)到配置屬性中,命令行參數(shù)通過(guò) -- 符號(hào)設(shè)置,比如 --server.port=8080。命令行參數(shù)比配置文件具有更高的優(yōu)先級(jí)。
通過(guò)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
通過(guò)命令行參數(shù):
$ java -jar myapp.jar --spring.application.json='{"my":{"name":"test"}}'
External Application Properties
Spring Boot啟動(dòng)過(guò)程中從如下路徑自動(dòng)調(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)先級(jí)(由低到高),后面的配置文件會(huì)覆蓋掉前面的配置文件。配置文件讀取后會(huì)被加載到會(huì)被加載的Spring Environment的PropertySources 中。
application是默認(rèn)的配置文件名,可以通過(guò)如下方式修改:
$ java -jar myproject.jar --spring.config.name=myproject
也可以通過(guò)環(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)也不會(huì)報(bào)錯(cuò)。否則不指定optional、配置文件不存在的話,Spring Boot啟動(dòng)過(guò)程中會(huì)拋出ConfigDataLocationNotFoundException異常。
全局變量spring.config.on-not-found設(shè)置為ignore,可以讓Spring Boot忽略所有的配置文件不存在異常、繼續(xù)啟動(dòng)系統(tǒng):
SpringApplication.setDefaultProperties(…) or with a system/environment variable.
spring.config.name, spring.config.location, and spring.config.additional-location等三個(gè)參數(shù)在Spring Boot項(xiàng)目啟動(dòng)的早期就會(huì)被調(diào)用,所以,必須通過(guò)環(huán)境屬性指定、而不能通過(guò)配置文件的方式指定。
spring.config.location支持profile。
Wildcard Locations
帶 的配置文件位置的含義是:Spring Boot讀取配置文件的時(shí)候,指定位置的子目錄也被包含在內(nèi)。對(duì)于有多個(gè)配置文件的應(yīng)用, 配置方式會(huì)比較方便。
默認(rèn)情況下,Spring Boot會(huì)包含 config/*/ 作為其默認(rèn)的配置文件搜索路徑。意思是jar包下的config路徑及其子目錄下的配置文件都會(huì)生效。
可以在spring.config.location或spring.config.additional-location參數(shù)中使用 * 指定配置文件。
Profile Specific Files
這一特性主要是為了支持應(yīng)用在多個(gè)環(huán)境下采用不同配置參數(shù)的場(chǎng)景,比如開(kāi)發(fā)環(huán)境、測(cè)試環(huán)境、生產(chǎn)環(huán)境,同一參數(shù)在這三個(gè)不同的環(huán)境下的參數(shù)配置不同,如果在系統(tǒng)部署的時(shí)候手工切換(相信之前有好多項(xiàng)目確實(shí)就是這么干的),很有可能會(huì)由于操作失誤導(dǎo)致嚴(yán)重問(wè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.
通過(guò)spring.profiles.active參數(shù)指定profile后,相同位置存在多個(gè)相同配置文件(名字相同、profile不同)的情況下,指定的profile文件會(huì)生效。比如,spring.profiles.active指定為prod,live,當(dāng)前路徑下如果同時(shí)存在application.yml、application-prod.yml、application-live.yml,那么,如果三個(gè)配置文件中都存在同一項(xiàng)配置,則application-live.yml中的配置勝出(會(huì)生效)。
以下描述了“后來(lái)者勝出”策略的生效方式,通過(guò)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
建議盡可能用最簡(jiǎn)單的方式進(jìn)行配置:指定profile的情況下,盡可能不將同一類(lèi)型的(比如某一三方API連接參數(shù))、不同環(huán)境(比如測(cè)試、開(kāi)發(fā)、生產(chǎn))的配置文件放置在不同的路徑下,以免引起誤傷!
Importing Additional Data
Spring Boot支持通過(guò)spring.config.import定義配置文件路徑,Spring Boot啟動(dòng)過(guò)程中從指定路徑導(dǎo)入配置內(nèi)容。
比如在application.properties文件中指定:
spring.application.name=myapp
spring.config.import=optional:file:./dev.properties
則當(dāng)前路徑下如果存在dev.properties文件的話,Spring Boot會(huì)導(dǎo)入該文件的配置內(nèi)容。并且,dev.properties配置文件中的內(nèi)容優(yōu)先級(jí)高于定義他的文件(上例中的application.properties)。以上案例中如果dev.properties文件中存在spring.application.name,會(huì)覆蓋掉application.properties文件中的值myapp。
以上案例中,Spring Boot會(huì)首先讀取application.properties文件中的配置內(nèi)容,之后讀取dev.properties文件中的配置內(nèi)容并覆蓋掉application.properties文件中的相同配置內(nèi)容。因此,application.properties文件中spring.config.import的定義位置無(wú)關(guān)緊要,不管放在spring.application.name的前面、還是后面,都會(huì)覆蓋掉application.properties文件中的spring.application.name值。
spring.config.import配置支持profile。
Importing Extensionless Files
有些應(yīng)用的配置文件沒(méi)有擴(kuò)展名,Spring Boot可以通過(guò) [ ] 支持導(dǎo)入。
比如配置文件是/etc/config/myconfig,文件格式是yaml,則可以配置為:
spring.config.import=file:/etc/config/myconfig[.yaml]
Using Configuration Trees
通過(guò)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兩個(gè)文件:
etc/
config/
myapp/ username password
則myapp.username和myapp.password 將會(huì)注入到Environment的properties中。
Property Placeholders
參數(shù)可以通過(guò)占位符配置,比如:
app.name=MyApp
app.description=${app.name} is a Spring Boot application written by ${username:Unknown}
占位符app.name會(huì)被MyApp替代,如果系統(tǒng)中沒(méi)有username這個(gè)配置值的話,系統(tǒng)會(huì)以冒號(hào) : 后的值Unknown作為默認(rèn)值。
Working With Multi-Document Files
Spring Boot支持將同一個(gè)物理文件在邏輯上拆分成多個(gè)文件來(lái)處理。
比如,yaml文件,三個(gè)短橫線 --- 表示邏輯上一個(gè)配置文件的結(jié)束、另外一個(gè)配置文件的開(kāi)始:
spring: application: name: "MyApp" --- spring: application: name: "MyCloudApp" config: activate: on-cloud-platform: "kubernetes"
properties文件,#--- 或者 !--- 表示邏輯上一個(gè)配置文件的結(jié)束、另外一個(gè)配置文件的開(kāi)始:
spring.application.name=MyApp #--- spring.application.name=MyCloudApp spring.config.activate.on-cloud-platform=kubernetes
后面的配置文件內(nèi)容將會(huì)覆蓋掉前面配置文件的,上述案例的spring.application.name取值為MyCloudApp。
Activation Properties
通過(guò)spring.config.activate.*參數(shù)設(shè)置配置文件的內(nèi)容僅在指定的激活條件下生效,Spring Boot支持如下激活條件:
- on-profile:僅針對(duì)指定的profile生效。
- on-cloud-platform:僅針對(duì)指定的云平臺(tái)參數(shù)生效。
比如:
myprop=always-set #--- spring.config.activate.on-cloud-platform=kubernetes spring.config.activate.on-profile=prod | staging myotherprop=sometimes-set
---下面的(第二個(gè)邏輯文件內(nèi)容)僅針對(duì)云平臺(tái)kubernetes、以及profile為 prod或者staging生效。
Working With YAML
YAML格式的配置文件需要SnakeYAML包的支持,spring-boot-starter自動(dòng)包含了SnakeYAML包,所以Spring Boot項(xiàng)目是默認(rèn)支持YAML配置文件的。
Type-safe Configuration Properties
Spring Boot提供兩種不同的配置參數(shù)綁定方式,一種是通過(guò)@Value注解,另外一種是Type-safe Configuration Properties:
@Value注解使用起來(lái)比較方便,但是個(gè)人認(rèn)為不利于代碼管理,因?yàn)榕渲脜?shù)的綁定會(huì)分散在代碼各處。
- 綁定到JavaBean屬性:通過(guò)@ConfigurationProperties("my.service")注解直接綁定打JavaBean的屬性上。
- 通過(guò)構(gòu)造器綁定:通過(guò)@ConfigurationProperties("my.service")注解、構(gòu)造器參數(shù)完成綁定。
- 通過(guò)@EnableConfigurationProperties(SomeProperties.class)注解、指定特定的java類(lèi)完成綁定。
- 通過(guò)@ConfigurationPropertiesScan注解,采用配置文件屬性掃描的方式完成綁定(類(lèi)似于IoC容器注入bean是的組件掃描機(jī)制)。
- 通過(guò)@Configuration、 @ConfigurationProperties以及@Bean結(jié)合的方式完成綁定。
Relaxed Binding
Spring Boot的Relaxed Binding- 寬松綁定看,指的是SpringBoot在綁定配置文件參數(shù)的java配置類(lèi)的屬性上的時(shí)候,提供一種寬松的匹配規(guī)則,在配置文件中的配置和javabean中的屬性名稱(chēng)不是完全一一對(duì)應(yīng)的情況下,也可以實(shí)現(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)容絕大部分來(lái)之與Spring Boot官網(wǎng),Spring Boot提供了非常強(qiáng)大、靈活的配置文件綁定方式,但是建議大家在實(shí)際項(xiàng)目中采用最基礎(chǔ)的、最簡(jiǎn)單的方式進(jìn)行配置,不沖突、無(wú)歧義、能實(shí)現(xiàn)目標(biāo)的前提條件下,越簡(jiǎn)單越好,更多關(guān)于Springboot Externalized Configuration的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java集合之Comparable和Comparator接口詳解
Java提供了Comparable接口與Comparator接口,它們?yōu)閿?shù)組或集合中的元素提供了排序邏輯,實(shí)現(xiàn)此接口的對(duì)象數(shù)組或集合可以通過(guò)Arrays.sort或Collections.sort進(jìn)行自動(dòng)排序。本文將通過(guò)示例講講它們的使用,需要的可以參考一下2022-12-12SpringBoot整合Redis實(shí)現(xiàn)附近位置查找(LBS)功能
Redis 提供了 GEO 數(shù)據(jù)結(jié)構(gòu),可以高效地存儲(chǔ)和查詢(xún)地理位置數(shù)據(jù),本文將介紹如何使用 Spring Boot + Redis 來(lái)實(shí)現(xiàn)附近位置查找,需要的可以了解下2025-03-03IDEA調(diào)試源碼小技巧之辨別抽象類(lèi)或接口多種實(shí)現(xiàn)類(lèi)的正確路徑
這篇文章主要介紹了IDEA調(diào)試源碼小技巧之辨別抽象類(lèi)或接口多種實(shí)現(xiàn)類(lèi)的正確路徑,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01Lucene實(shí)現(xiàn)索引和查詢(xún)的實(shí)例講解
下面小編就為大家分享一篇Lucene實(shí)現(xiàn)索引和查詢(xún)的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12Java進(jìn)行Appium自動(dòng)化測(cè)試的實(shí)現(xiàn)
這篇文章主要介紹了Java進(jìn)行Appium自動(dòng)化測(cè)試的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01IDEA項(xiàng)目中配置Maven鏡像源(下載源)的詳細(xì)過(guò)程
Maven是一個(gè)能使我們的java程序開(kāi)發(fā)節(jié)省時(shí)間和精力,是開(kāi)發(fā)變得相對(duì)簡(jiǎn)單,還能使開(kāi)發(fā)規(guī)范化的工具,下面這篇文章主要給大家介紹了關(guān)于IDEA項(xiàng)目中配置Maven鏡像源(下載源)的詳細(xì)過(guò)程,需要的朋友可以參考下2024-02-02Maven+SSM框架實(shí)現(xiàn)簡(jiǎn)單的增刪改查
這篇文章主要介紹了Maven+SSM框架實(shí)現(xiàn)簡(jiǎn)單的增刪改查,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-03-03Java編程中實(shí)現(xiàn)歸并排序算法的實(shí)例教程
這篇文章主要介紹了Java編程中實(shí)現(xiàn)歸并排序算法的實(shí)例教程,包括自底向上的歸并排序的實(shí)現(xiàn)方法介紹,需要的朋友可以參考下2016-05-05ShardingSphere數(shù)據(jù)庫(kù)讀寫(xiě)分離算法及測(cè)試示例詳解
這篇文章主要為大家介紹了ShardingSphere數(shù)據(jù)庫(kù)讀寫(xiě)分離算法及測(cè)試示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03