Ⅰ Springboot 讀取配置文件原理
Springboot 讀取配置文件(application.yaml, application.properties)的過程發生在SpringApplication#prepareEnvironment() 階段,而prepareEnvironment又屬於整個Springboot 應用啟動的非常前置階段,因為Environment的准備是後續bean創建的基礎。讓我們來一探啟動是的詳細code。除去StopWatch這些code,可以發現prepareEnvironment 發生在SpringApplication#run 這在整個應用啟動的多步實質性操作中幾乎是第一步。
而prepareEnvironment中最重要的是通過觸發listener(EventPublishingRunListener)來通過#multicastEvent發出。
而#multicastEvent的實現其實也很簡單,找到相關的監聽的listener,然後一個個的調用他們的Listener#onApplicationEvent(event)方法,而這其中就包括了處理configuration文件的listener。
在Springboot 2.4.0 之前這個處理configuration 文件的lister是ConfigFileApplicationListener,在2.4.0之後,處理configuration 文件的lister是,並且對configuration文件的載入做了較大的改變,導致一些行為可能出現了變化,這也就是下面要詳細講的內容。
Springboot 2.4.0之後,configuration 文件的load順序按照優先順序是如下順序(序號大的會被小的覆蓋):
和之前版本比較,整體的屬性載入順序並無調整,只有Application properties(14,15)這里有順序的調整,具體調整為:
如果存在多個active的profiles,例如[Test, Dev], 那麼對於同時存在兩個profile 配置文件中的配置,後面的profile里的配置(Dev)會覆蓋前面profile(Test)里配置的值。
前面講了這么多,終於要引出Springboot 2.4之後配置文件載入的行為變化了。
考慮這樣的情況,如果我想在跑Springboot test的時候指定特定的profile,那麼可以在Test class中加入@ActiveProfile("Test")。 如果我的應用中存在的某個自定義listener中,會根據當前environment 設置profile,如env.addActiveProfile("Dev")。
當前就會有兩個active profile,由於springboot-test會在調用application#run 前利用DefaultActiveProfilesResolver把@ActiveProfile註解定義的profile(Test)先加入了active的profile,等test run的時候 env.addActiveProfile("Dev") 又會把"Dev"也作為active profile 加入,這時候當前的active profile便為["Test", "Dev"]。
據上面介紹,後面的profile(Dev)對應的configuration 會覆蓋前面的(Test)。可Springboot 2.4.0之前的版本為我們做了調整,讓Test class中@ActiveProfile內定義的profile所對應的配置文件成為最高優先順序。
剛才提到在Springboot 2.4.0 之前這個處理configuration 文件的lister是ConfigFileApplicationListener,我們
來看看ConfigFileApplicationListener的相關code。
查看initializeProfiles(),發現此時對profile的順序做了調整,將activatedViaProperty (Test) 放在最後add,於是profile的順序就變成了[Dev, Test]。
在profiles.poll()時原本profile的順序已經倒了過來,已經變為[Dev, Test], 在load()方法中由於後置的Test profile,application-Test.yaml中的值最終生效了。
可是到了Springboot2.4.0之後,ConfigFileApplicationListener被deprecated了,取而代之的是,通過調用來完成configuration載入。
.java
.java
只是老老實實的set了active profile,並沒有調換profile的順序。最後調用定義在spring.factories中的resource loader class來load 配置文件。
YamlPropertySourceLoader.java
插一句,Springboot為我們提供了很好的yaml文件parse的code,當你需要解析yaml文件時不妨直接參考Springboot的YamlPropertySourceLoader
這樣一旦應用升級到Springboot 2.4.0之後相同的test code會使用application-Dev.yaml中配置的值,造成了test結果的改變。
如果要解決這個問題,根據上面介紹的配置文件優先順序順序,可以在@SpringbootTest中設置properties 來作為最終的配置覆蓋當前profile對應的配置。
了解一個框架很不容易,一個小小的變化都有可能造成應用的行為變化,唯有刨根問底,不斷總結才是framework人解決一切問題的不變的方法論。
Ⅱ SpringBoot 如何優雅讀取配置文件10分鍾教你搞定
很多時候我們需要將一些常用的配置信息比如阿里雲 oss 配置、發送簡訊的相關信息配置等等放到配置文件中。
下面我們來看一下 Spring 為我們提供了哪些方式幫助我們從配置文件中讀取這些配置信息。
application.yml 內容如下:
wuhan2020: 2020年初武漢爆發了新型冠狀病毒,疫情嚴重,但是,我相信一切都會過去!武漢加油!中國加油!my-profile:name: Guide哥email: [email protected]:location: 湖北武漢加油中國加油books: -name: 天才基本法description: 二十二歲的林朝夕在父親確診阿爾茨海默病這天,得知自己暗戀多年的校園男神裴之即將出國深造的消息——對方考取的學校,恰是父親當年為她放棄的那所。 -name: 時間的秩序description: 為什麼我們記得過去,而非未來?時間「流逝」意味著什麼?是我們存在於時間之內,還是時間存在於我們之中?卡洛·羅韋利用詩意的文字,邀請我們思考這一亘古難題——時間的本質。 -name: 了不起的我description: 如何養成一個新習慣?如何讓心智變得更成熟?如何擁有高質量的關系? 如何走出人生的艱難時刻?
1.通過 @value 讀取比較簡單的配置信息
使用 @Value("${property}") 讀取比較簡單的配置信息:
@Value("${wuhan2020}")String wuhan2020;
需要注意的是 @value這種方式是不被推薦的,Spring 比較建議的是下面幾種讀取配置信息的方式。
2.通過@ConfigurationProperties讀取並與 bean 綁定
LibraryProperties 類上加了 @Component 註解,我們可以像使用普通 bean 一樣將其注入到類中使用。
importlombok.Getter;importlombok.Setter;importlombok.ToString;importorg.springframework.boot.context.properties.ConfigurationProperties;importorg.springframework.context.annotation.Configuration;importorg.springframework.stereotype.Component;importjava.util.List;@Component@ConfigurationProperties(prefix ="library")@Setter@Getter@{privateString location;privateList books;@Setter@Getter@ToStringstaticclassBook{ String name; String description; }}
這個時候你就可以像使用普通 bean 一樣,將其注入到類中使用:
packagecn.javaguide.readconfigproperties;importorg.springframework.beans.factory.InitializingBean;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;/** *@authorshuang.kou */@ntsInitializingBean{privatefinalLibraryProperties library;(LibraryProperties library){this.library = library; }publicstaticvoidmain(String[] args){ SpringApplication.run(.class,args); }@(){ System.out.println(library.getLocation()); System.out.println(library.getBooks()); }}
控制台輸出:
湖北武漢加油中國加油[LibraryProperties.Book(name=天才基本法, description........]
3.通過@ConfigurationProperties讀取並校驗
我們先將application.yml修改為如下內容,明顯看出這不是一個正確的 email 格式:
my-profile:name: Guide哥email: koushuangbwcx@
ProfileProperties 類沒有加 @Component 註解。我們在我們要使用ProfileProperties 的地方使用@
EnableConfigurationProperties注冊我們的配置 bean:
importlombok.Getter;importlombok.Setter;importlombok.ToString;importorg.springframework.boot.context.properties.ConfigurationProperties;importorg.springframework.stereotype.Component;importorg.springframework.validation.annotation.Validated;importjavax.validation.constraints.Email;importjavax.validation.constraints.NotEmpty;/***@authorshuang.kou*/@Getter@Setter@ToString@ConfigurationProperties("my-profile")@{@NotEmptyprivateString name;@Email@NotEmptyprivateString email;//配置文件中沒有讀取到的話就用默認值privateBooleanhandsome =Boolean.TRUE;}
具體使用:
packagecn.javaguide.readconfigproperties;importorg.springframework.beans.factory.InitializingBean;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.boot.context.properties.EnableConfigurationProperties;/** *@authorshuang.kou */@SpringBootApplication@EnableConfigurationProperties(ProfileProperties.class){privatefinalProfileProperties profileProperties;(ProfileProperties profileProperties){this.profileProperties = profileProperties; }publicstaticvoidmain(String[] args){ SpringApplication.run(.class,args); }@(){ System.out.println(profileProperties.toString()); }}
因為我們的郵箱格式不正確,所以程序運行的時候就報錯,根本運行不起來,保證了數據類型的安全性:
Binding to target org.springframework.boot.context.properties.bind.BindException:Failedtobindpropertiesunder'my-profile'to cn.javaguide.readconfigproperties.ProfileProperties failed:Property:my-profile.emailValue:koushuangbwcx@Origin:classpathresource[application.yml]:5:10Reason:mustbeawell-formedemailaddress
我們把郵箱測試改為正確的之後再運行,控制台就能成功列印出讀取到的信息:
ProfileProperties(name=Guide哥, [email protected], handsome=true)
4.@PropertySource讀取指定 properties 文件
importlombok.Getter;importlombok.Setter;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.context.annotation.PropertySource;importorg.springframework.stereotype.Component;@Component@PropertySource("classpath:website.properties")@Getter@SetterclassWebSite{@Value("${url}")privateString url;}
使用:
@Autowiredprivate WebSite webSite;System.out.println(webSite.getUrl());//https://javaguide.cn/
5.題外話:Spring 載入配置文件的優先順序
Spring 讀取配置文件也是有優先順序的,直接上圖:
原文鏈接:https://www.toutiao.com/a6791445278911103500/?log_from=7f5fb8f9b4b47_1640606437752
Ⅲ springboot獲取復雜的list配置文件
使用springboot獲取以List類型為主的配置項 (包含list嵌套的使用)
1.在application.yml 主配置文件中配置以smtpmail開頭的配置項
(方法2)創建 ApplicationConfig.java 配置類用於獲取application.yml所有配置
@ConfigurationProperties 註解作用在方法上
3.使用單元測試獲取屬性
Ⅳ Spring Boot 第二彈,配置文件詳解-史上最全
Spring Boot 官方 提供了兩種常用的配置文件格式,分別是 properties 、 YML 格式。相比於 properties 來說, YML 更加年輕,層級也是更加分明。 強烈推薦使用 YML 格式
Spring Boot項目 啟動會掃描以下位置的 application.properties 或者 application.yml 作為默認的配置文件.
徒手撕源碼
內部類Loader的load方法
getSearchLocations()方法
asResolvedSet()
下面給出優先順序 從高到低 的配置文件排列順序:
以設置應用埠為例 初體驗Spring Boot配置文件
properties後綴結尾(application.properties)
yml/yaml後綴結尾(application.yml/application.yaml)
數字,字元串,布爾,日期
對象、Map
數組
數字,字元串,布爾,日期
對象、Map
數組
@ConfigurationProperties(prefix = "person")詳解
標注在類上
標注在方法上
綜上所述
@ConfigurationProperties 註解能夠輕松的讓配置文件跟實體類綁定在一起。
值得關注的是: @ConfigurationProperties 這個註解僅僅是支持從 Spring Boot的默認配置文件 中取值,也就是 application.properties 、 application.yml 、 application.yaml ,那我們如何從自定義配置文件取值呢???
別著急,有解決辦法,那就是再加一個註解: @PropertySource(value = "classpath:custom-profile.properties") ,下面會有對 @PropertySource 註解的介紹。請耐心往下面看。
使用@PropertySource註解
對應配置文件
創建兩個配置文件 custom-profile.yml、custom-profile1.yml ,如下去引入。
我們可以通過控制變數法進行測試,具體過程我這里就不贅述了。
直接說 結論 吧: Spring載入順序 為 從左到右順序載入 ,後載入的會 覆蓋 先載入的屬性值。
另外需要注意的是 : @PropertySource 默認載入 xxx.properties類型 的配置文件,不能載入 YML格式 的配置文件。如何解決呢?下面來解決這一問題
對應配置文件:
編寫PropertiesController
擴展功能
application.yml 主配置文件
application-dev.yml 開發配置文件
application-prod.yml 生產配置文件
application-test.yml 測試配置文件
(1)主配置文件:配置激活選項
(2)其他配置文件:指定屬於哪個環境(同yml,只不過表現形式是 key=value 的,三個配置文件分別是: application-dev.properties , application-prod.properties , application-test.properties )
無論是使用上述 多文檔塊 的方式,還是新建 application-test.yml 文件,都可以在配置文件中指定 spring.profiles.active=test 激活指定的profile。
感謝閱讀小生文章。祝大家早日富可敵國,實現財富自由。
寫文不易 ,一定要 點贊、評論、收藏哦 , 感謝感謝感謝!!!
Ⅳ springboot配置文件總結
springboot 本身支持多種靈活的配置方式,為開發 springboot 程序帶來了很大的靈活性和擴展性,但是同時由於太靈活,經常會導致明明配置了相關屬性,卻沒有生效。
本文總結了 springboot 配置文件的原理以及多個配置文件生效的順序。
springboot 配置文件支持靈活的路徑,以及靈活的文件名,用一個變數表達式總結如下:
部分源碼如下:
當滿足上述變數表達式的配置文件有多個時,會有一個配置的優先順序。假設
上面每個條件組合起來,則最多有配置文件如下,且順序從上到下:
獲取屬性時,按從上到下的順序遍歷由上述文件生成的屬性資源對象 PropertySource ,如果遇到匹配的key直接返回。
總結一下:就是如果同一個key的屬性只出現一次,則直接取該值即可。如果同一個key的屬性出現多次,則取順序靠前的屬性資源對象。另外其中每個文件都是可選的。
需要注意的一點是:如果在同一個 location 下配置了多個文件名一樣的文件,則只會取一個,比如在 classpath:/ ,有如下兩個文件 application.yml :
則只會根據 classloader 的 classpath 列表,選取第一個出現的文件。因為 springboot 載入配置文件時最底層是使用的下面的方法:
這兩個方法只會獲取 classloader 類的 ucp 屬性裡面第一個匹配到的值。如果對 springboot 自身的機制不滿意,想獲取所有的classpath:/路徑下面的 applicaiton.yml 文件,可以使用下面的方法:
本文總結了 springboot 配置文件的原理以及多個配置文件生效的順序。如果存在增加了配置文件或者在配置文件裡面增加了屬性卻沒有生效,可以參考上面的 springboot 配置文件表達式和配置文件生效順序進行排查。
後面還會有一篇文章討論基於 springboot 配置原理如何實現自定義的配置讀取方式。
Ⅵ 二、SpringBoot的配置--yaml
SpringBoot使用一個全局的配置文件,配置文件名是固定的;
配置文件的作用:修改SpringBoot自動配置的默認值;SpringBoot在底層都給我們自動配置好;
YAML 是一個標記語言
標記語言:
以前的配置文件;大多都使用的是xxx.xml文件
YAML:以數據為中心,比json、xml等更適合做配置文件
YAML:配置例子
XML:
k:(空格)v : 表示一對鍵值對(空格必須有)
以空格的縮進來控制層級關系;只要是左對齊的一列數據,都是同一個層級的
屬性和值也是大小寫敏感;
k: v :字面直接來寫;
字元串默認不用加上單引號或者雙引號;
"" :雙引號;不會轉義字元串裡面的特殊字元; 特殊字元會作為本身想表示的意思
name : "zhangsan lisi" :輸出 : zhangsan 換行 lisi
'' :單引號;會轉義特殊字元,特殊字元最終只是一個普通的字元串數據
name: 'zhangsan lisi' : 輸出 ; zhangsan lisi
k: v : 在下一行來寫對象的屬性和值的關系 ;注意縮進
對象還是 k: v 的方式
行內寫法:
用- 值表示數組中的一個元素
行內寫法
配置文件
javaBean:
我們可以導入配置文件處理器,以後編寫配置就有提示了
調整 圖示:
配置文件yml還是properties他們都能獲取到值;
如果說,我們只是在某個業務邏輯中需要獲取一下配置文件中的某項值,使用@Value
如果說,我們專門編寫一個javaBean來和配置文件進行映射,我們就直接使用@ConfigurationProperties
@ImportResource:導入Spring的配置文件,讓配置文件裡面的內容生效
SpringBoot裡面沒有Spring的配置文件,我們自己編寫的配置文件,也不能自動識別;
想讓Spring的配置文件生效,載入進來;@ImportResource標注在一個配置類上
不來編寫Spring的配置文件
Spring Boot推薦給容器添加組件的方式;推薦全註解的方式
1、配置類@Configuration------>Spring配置文件
2、使用@Bean給容器中添加組件
我們在主配置文件編寫的時候,文件名可以是application-{profile}.properties/yml
默認使用application.properties的配置
1、在配置文件中指定spring.profiles.active=dev
2、在命令行:
java -jar spring-boot-02-config.jar --spring.profiles.active=dev;
可以直接在測試的時候,配置傳入命令行參數
3.虛擬機參數
-Dspring.profiles.active=dev
springboot 啟動會掃描以下位置的application.properties或者application.yml文件作為Spring Boot的默認配置文件
-file:./config/
-file:./
-classpath:/config/
-classpath:/
優先順序由高到低,高優先順序的配置會覆蓋低優先順序的配置
SpringBoot會從這四個位置載入主配置文件:互補配置
==我們還可以通過spring.config.location來改變默認的配置文件位置==
項目打包好以後,我們可以使用命令行參數的形式,啟動項目的時候來指定配置文件的新位置;指定配置文件和默認載入的這些配置文件共同起作用互補配置;
java -jar spring-boot-02-config.jar --spring.config.location=G:/application.properties
==SpringBoot也可以從以下位置載入配置;優先順序從高到低;高優先順序的配置低優先順序的配置,所有的配置會形成互補配置==
1.命令行參數
2.來自java:comp/env的JNDI屬性
3.java系統屬性
4.操作系統環境變數
5.RandomValuePropertySource配置的random.*屬性值
==有jar包外箱jar包內進行尋找==
==優先載入帶profile==
6.jar包外部的application-{profile}.properties 或 application.yml(帶spring.profile)配置文件
7.jar包內部的application-{profile}.properties 或 application.yml(帶spring.profile)配置文件
==再來載入不帶profile==
8.jar包外部的application.properties或者application.yml(不帶spring.profile)配置文件
9.jar包內部的application.properties或者application.yml(不帶spring.profile)配置文件
精髓:
1》springboot啟動會載入大量的自動配置類
2》我們看我們需要的功能有沒有springboot默認寫好的自動配置類
3》我們再來看這個自動配置類中到底配置了那些組件;(只要我們要用的組件有,我們就不需要再來配置了)
4》給容器中自動配置類添加組件的時候,會從properties類中獲取某些屬性,我們就可以在配置文件中指定這些屬性的值
Ⅶ springboot常用註解
springboot常用註解有@SpringBootApplication;@Repository;@Service;@RestController;@ResponseBody。
3、starter 是 SpringBoot 中一種非常重要的機制,它可以繁雜的配置統一集成到 starter 中,我們只需要通過 maven 將 starter 依賴引入到項目中,SpringBoot 就能自動掃描並載入相應的默認配置。starter 的出現讓開發人員從繁瑣的框架配置中解放出來,將更多的精力專注於業務邏輯的開發,極大的提高了開發效率。
Ⅷ Spring Boot | 配置文件
創建 Spring Boot 項目默認會在 src/main/resources 目錄下生成一個全局配置文件 application.properties 。全局配置文件的作用是對一些默認配置進行修改。
Spring Boot 的參數配置除了使用 properties 文件之外,還可以使用 yml 文件。如果你喜歡用 yml 格式的配置文件可以將 application.properties 修改為 application.yml 。
Spring Boot 應用程序有多種設置途徑。Spring Boot 能從多種屬性源獲得屬性,包括如下幾處:
這個列表按照優先順序排序,也就是說,任何在高優先順序屬性源里設置的屬性都會覆蓋低優先順序屬性源里設置的相同屬性。例如,命令行參數會覆蓋其它屬性源里的屬性。
application.properties 和 application.yml 文件能放下如下四個位置:
同樣,這個列表也是按照優先順序排序。也就是說,/config 子目錄里 application.properties 會覆蓋應用程序 classpath 里的 application.properties 中的相同屬性。
Ⅸ SpringBoot的配置文件有哪幾種格式
SpringBoot中的配置文件來主要有三種格式,自properties、yaml、和xml方式。
- 其中properties格式配置文件後綴是.properties,配置項為:server.port = 9090
- yaml格式配置文件後綴是.yml,配置項是:server.port: 9090
在SpringBoot中,使用最廣泛的配置文件是yaml,yaml之所以流行,除了他配置語法精簡之外,還因為yaml是一個跨編程語言的配置文件。
在SpringBoot中,除了yaml之外,properties也比較常用,但是XML幾乎不用,看得出來Spring團隊非常痛恨XML配置文件!認為它不是一個好的語言。
如果你對常見的配置文件有哪幾種格式不熟悉,就去黑馬程序員官網視頻庫看免費視頻。