SpringBoot源碼剖析之屬性文件加載原理
前言
首先我們來看一個問題。就是我們在創(chuàng)建SpringBoot項目的時候會在對應的application.properties或者application.yml文件中添加對應的屬性信息,我們的問題是這些屬性文件是什么時候被加載的?如果要實現自定義的屬性文件怎么來實現呢?本文來給大家揭曉答案:
1.找到入口
結合我們前面介紹的SpringBoot中的監(jiān)聽事件機制,我們首先看下SpringApplication.run()方法,在該方法中會針對SpringBoot項目啟動的不同的階段來發(fā)布對應的事件。
處理屬性文件加載解析的監(jiān)聽器是 ConfigFileApplicationListener
,這個監(jiān)聽器監(jiān)聽的事件有兩個。
而我們進入SpringApplication.prepareEnvironment()方法中發(fā)布的事件其實就是ApplicationEnvironmentPreparedEvent事件。進入代碼查看。
進行進入
繼續(xù)進入會看到對應的發(fā)布事件:ApplicationEnvironmentPreparedEvent
結合上篇文件的內容,我們知道在initialMulticaster中是有ConfigFileApplicationListener這個監(jiān)聽器的。
那么在此處觸發(fā)了配置環(huán)境的監(jiān)聽器,后續(xù)的邏輯就應該進入對應的
2.ConfigFileApplicationListener
2.1 主要流程分析
接下來我們看下ConfigFileApplicationListener中具體的如何來處理配置文件的加載解析的。
根據邏輯我們直接進入onApplicationEnvironmentPreparedEvent()方法中。
系統(tǒng)提供那4個不是重點,重點是 ConfigFileApplicationListener 中的這個方法處理.
直接進入ConfigFileApplicationListener.postProcessEnvironment()方法。
在進入addPropertySources()方法中會完成兩個核心操作,1。創(chuàng)建Loader對象,2。調用Loader對象的load方法,
2.2 Loader構造器
現在我們來看下在Loader構造器中執(zhí)行了什么操作。
通過源碼我們可以發(fā)現在其中獲取到了屬性文件的加載器、從spring.factories文件中獲取,對應的類型是 PropertySourceLoader
類型。
而且在loadFactories方法中會完成對象的實例化。
到這Loader的構造方法執(zhí)行完成了,然后來看下load()方法的執(zhí)行。先把代碼貼上
void load() { FilteredPropertySource.apply(this.environment, DEFAULT_PROPERTIES, LOAD_FILTERED_PROPERTY, (defaultProperties) -> { // 創(chuàng)建默認的profile 鏈表 this.profiles = new LinkedList<>(); // 創(chuàng)建已經處理過的profile 類別 this.processedProfiles = new LinkedList<>(); // 默認設置為未激活 this.activatedProfiles = false; // 創(chuàng)建loaded對象 this.loaded = new LinkedHashMap<>(); // 加載配置 profile 的信息,默認為 default initializeProfiles(); // 遍歷 Profiles,并加載解析 while (!this.profiles.isEmpty()) { // 從雙向鏈表中獲取一個profile對象 Profile profile = this.profiles.poll(); // 非默認的就加入,進去看源碼即可清楚 if (isDefaultProfile(profile)) { addProfileToEnvironment(profile.getName()); } load(profile, this::getPositiveProfileFilter, addToLoaded(MutablePropertySources::addLast, false)); this.processedProfiles.add(profile); } // 解析 profile load(null, this::getNegativeProfileFilter, addToLoaded(MutablePropertySources::addFirst, true)); // 加載默認的屬性文件 application.properties addLoadedPropertySources(); applyActiveProfiles(defaultProperties); }); }
然后我們進入具體的apply()方法中來查看。
中間的代碼都有注釋,主要是處理profile的內容。
首先是getSearchLocations()方法,在該方法中會查詢默認的會存放對應的配置文件的位置,如果沒有自定義的話,路徑就是 file:./config/ file:./ classpath:/config/ classpath:/ 這4個
然后回到load方法中,遍歷4個路徑,然后加載對應的屬性文件。
getSearchNames()獲取的是屬性文件的名稱。如果自定義了就加載自定義的
否則加載默認的application文件。
再回到前面的方法
進入load方法,會通過前面的兩個加載器來分別加載application.properties和application.yml的文件。
loader.getFileExtensions()獲取對應的加載的文件的后綴。
進入loadForFileExtension()方法,對profile和普通配置分別加載
繼續(xù)進入load方法
開始加載我們存在的application.properties文件。
2.3 properties加載
在找到了要加載的文件的名稱和路徑后,我們來看下資源加載器是如何來加載具體的文件信息的。
進入loadDocuments方法中,我們會發(fā)現會先從緩存中查找,如果緩存中沒有則會通過對應的資源加載器來加載了。
此處是PropertiesPropertySourceLoader來加載的。
進入loadProperties方法
之后進入load()方法看到的就是具體的加載解析properties文件中的內容了。感興趣的可以看下具體的邏輯,本文就給大家介紹到這里了。
總結
到此這篇關于SpringBoot源碼剖析之屬性文件加載原理的文章就介紹到這了,更多相關SpringBoot屬性文件加載原理內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring Security在標準登錄表單中添加一個額外的字段
這篇文章主要介紹了Spring Security在標準登錄表單中添加一個額外的字段,我們將重點關注兩種不同的方法,以展示框架的多功能性以及我們可以使用它的靈活方式。 需要的朋友可以參考下2019-05-05SpringCloud maven-assembly-plugin 多級目錄打包的實現
本文主要介紹了SpringCloud maven-assembly-plugin 多級目錄打包的實現,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-10-10