亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.430618.com 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

前言

關于nacos客戶端如何獲取到服務端的配置信息的主流程源碼分析和客戶端拉取服務端變更的主流程源碼分析在前兩篇文章都分析過了,雖然讀的人并不是很多,加起來也沒有200個人閱讀,也不知道是我寫的不好,還是大家對nacos的源碼并不感興趣,不過既然是系列教程,我們還是要堅持把這個小系列教程做完,本小節本來要介紹nacos和spring boot整合的主流程源碼分析的,但是思來想去,還是先花幾個小節把spring boot的啟動流程中涉及到的主要組件一起學習一下,這樣可能分析nacos和spring boot整合時候,大家理解的可能會快一點,達到事半功倍的效果

本文為原創文章,主要講解spring boot一個核心組件EnvironmentPostProcessor,閱讀本文大約7分鐘,如果覺得本文寫的不錯,請給一個點贊或者關注一下,您的支持是我寫作的最大動力

10分鐘搞懂SpringBoot的組件EnvironmentPostProcessor使用和原理

 

EnvironmentPostProcessor功能說明

EnvironmentPostProcessor從名字上看,叫做"環境后置處理器",它是一個接口,它可以再spring上下文啟動的時候,去初始化一些基本配置信息,將某些變量信息,加載到spring容器上下文中,更加通俗的理解就是它可以用來解析加載我們自定義額外properties

舉例來說:

1) 我們可以使用EnvironmentPostProcessor來加載json文件中的kv屬性,將其解析到全局的環境變量里面,然后使用@Value來獲取到信息

2)我們甚至可以使用EnvironmentPostProcessor來加載遠程的配置,例如我們可以使用這個組件加載nacos的服務器的配置信息

EnvironmentPostProcessor 實戰——加載本地json數據

step1.編寫測試數據

1.1.首先在spring boot的hello world項目的resource文件夾下新建一個測試的json——custom_properties文件,就寫兩個簡單的kv值

10分鐘搞懂SpringBoot的組件EnvironmentPostProcessor使用和原理

 

1.2.存在的位置在resources/json/custom_properties.json,格式如下

10分鐘搞懂SpringBoot的組件EnvironmentPostProcessor使用和原理

 

step2.自定義EnvironmentPostProcessor

2.1.新建BazingaJsonEnvironmentPostProcessor,這個類主要是讀取我們剛才寫的cutom_properties.json的文本信息,然后加載到spring的Environment中,BazingaJsonEnvironmentPostProcessor繼承我們今天的主角EnvironmentPostProcessor,這是一個接口,我們需要實現postProcessorEnvironment接口

10分鐘搞懂SpringBoot的組件EnvironmentPostProcessor使用和原理

 

這個接口就是首先讀取cutom_properties.json轉換成流,然后將流讀取成kv值,變成properties,最后寫入到ConfigurableEnvironment中去,這樣當spring的context開始初始化的時候,就能夠在ConfigurableEnvironment中讀取到變量,主要實現代碼如下

10分鐘搞懂SpringBoot的組件EnvironmentPostProcessor使用和原理

核心實現邏輯

2.2 我們有了自定義的BazingaJsonEnvironmentPostProcessor之后,還是不夠的,還缺一個驅動力,springboot啟動的時候,不會去主動讀取我們自定義的類的,所以我們還需要利用spring boot的SPI機制,來加載我們的環境后置處理器,我們再resources下新建一個文件夾META-INF,然后在META-INF下新建文件spring.factories,整體結構如下圖所示

10分鐘搞懂SpringBoot的組件EnvironmentPostProcessor使用和原理

spring.factories

2.3 文件的內容也是有規范的,我們要指定spring的接口具體的實現類是我們自定義的

10分鐘搞懂SpringBoot的組件EnvironmentPostProcessor使用和原理

 

到這邊為止,我們所有的配置就到此結束了,最后我們寫一個簡單的測試controller,來測試一下我們自定義的兩個KV能否在@Value這種注解中生效

10分鐘搞懂SpringBoot的組件EnvironmentPostProcessor使用和原理

 

我們整體的項目骨架圖如下圖所示

10分鐘搞懂SpringBoot的組件EnvironmentPostProcessor使用和原理

 

我們簡單地運行一下localhost:8080/json/hello,可以在瀏覽器中成功展示我們的"您好,世界",這樣我們就可以成功地將我們自定義的文件中的屬性值,讓spring boot加載到,并成功運用到我們真實的項目中去了,雖然很簡單,但是這個組件EnvironmentPostProcessor的使用套路,大家還是要掌握的,很多優秀的源代碼中都運用了這個套路,例如攜程的Apollo.

EnvironmentPostProcessor的原理講解

我們已經初步懂得了EnvironmentPostProcessor的使用技巧,還有它的作用,在講解原理之前,我們首先要記得一點,如果你有特殊的配置文件要加載的話,使用EnvironmentPostProcessor是很方便的,因為spring boot加載它的順序是所有組件中最靠前的,等下我們分析看源碼的時候,就能體會到這點了

這個源碼分析也很簡單,debug走一遍源碼5分鐘也就到了我們今天說的這個組件了,入口當然是我們的main函數了,我們只要看SpringApplication的源碼基本上就了解了

10分鐘搞懂SpringBoot的組件EnvironmentPostProcessor使用和原理

 

我們先打開SpringApplication#run方法

step1:我們第一個要關注的就是spring boot首先初始化了一個全局的事件監聽器,這個事件監聽器會伴隨著springboot的整個生命周期,這個我們以后也會多次接觸這個組件

10分鐘搞懂SpringBoot的組件EnvironmentPostProcessor使用和原理

初始化全局的事件監聽器EventPublishingRunListener

step2:接下來就是開始準備springboot所有配置文件存儲的倉庫Environment,這個其實也很好理解,spring是管理bean的,bean里面也有很多屬性,所以優先收集整個上下文的配置屬性信息,將其放在一個籃子(Environment)里面,然后以后想要什么,就從籃子里面去獲取,而不是在想要的時候,在去想辦法獲取,這樣會導致整個springboot的代碼變得不是很優雅

10分鐘搞懂SpringBoot的組件EnvironmentPostProcessor使用和原理

 

step3:我們進入prepareEnvironment方法

10分鐘搞懂SpringBoot的組件EnvironmentPostProcessor使用和原理

 

我們可以看到首先先調用getOrCreateEnvironment創建好一個"籃子",有了這個"籃子"我們才可以在這個"籃子"里面放我們想要的東西,所以我們可以接著看下一行的#configureEnvironment方法,例如System.setProperties之類信息會在這邊進行加載,放到籃子里面

10分鐘搞懂SpringBoot的組件EnvironmentPostProcessor使用和原理

 

主要是加載如下的配置文件,你不要小看這樣的配置文件,運維很有用,運維啟動啟動一般會配置啟動參數,其實也就是在這個地方,啟動參數被會spring boot解析到作為默認選項,加載到上下文中,作為啟動的核心參數啟動,但是一般這些參數叫做默認參數,優先級是最低的,如果你在代碼有同key值的時候,就會覆蓋運維配置的系統級變量值,這點我們平時開發的時候要注意,如下圖所示,這點很重要,不過不是我們今天的重點

10分鐘搞懂SpringBoot的組件EnvironmentPostProcessor使用和原理

 

其實就算大家不看spring的源碼,但是也知道spring有一個很牛的源碼原則就是"開閉原則","籃子"是spring自己造的,東西也是spring自己放的,不能讓我們這些使用者沒有一點機會去做點什么,肯定不是springboot的風格,所以spring就開了一個口子,簡單地說就是開了一個后門,貌似在說:我東西放完了,你有什么東西要放的啊,口子就在如下的代碼中

10分鐘搞懂SpringBoot的組件EnvironmentPostProcessor使用和原理

 

我們可以看到方法名叫做environmentPrepared,調用者是listener,是一個監聽器,也就是我們上文說的EventPublishingRunListener監聽器,就是像是在說:"同志們,籃子我已經弄好了,你們有啥東西想放的趕緊放,放完我準備開始用了"

最后我們跟著源碼debug,會到了ConfigFileApplicationListener的監聽器實例,它監聽的是一個ApplicationEnvironmentPreparedEvent,故其名曰"應用環境準備好事件",雖然有點繞口,也不通順,但是看到這邊我們就動了,springboot是靠一種事件訂閱的方式來做解耦合的,源碼如下

10分鐘搞懂SpringBoot的組件EnvironmentPostProcessor使用和原理

ConfigFileApplicationListener.JAVA

debug到現在,我們進入onApplicationEnvironmentPreparedEvent這個方法,就可以看到我們今天的主角的影子了,有請我們的主角登場

10分鐘搞懂SpringBoot的組件EnvironmentPostProcessor使用和原理

EnvironmentPostProcessor初次出現

我們可以看到當loadPostProcessors執行完之后,看方法名我們也是是加載當前項目中EnvironmentPostProcessor,然后排序,最后調用我們剛剛說的postProcessorEnvironment方法,這個方法的具體實現,也就是我們上文實戰小節的那個BazingaJSONEnvironmentPostProcessor的具體實踐了,到現在為止,我們已經跟蹤源碼知道整個加載的主流程了

現在還剩下最后一個問題,為啥我們要寫META-INF的spring.factorie配置文件了,答案就是在loadPostProcessors中了,這個方法是一個靜態方法,調用SpringFactoriesLoader的loadFactories方法

10分鐘搞懂SpringBoot的組件EnvironmentPostProcessor使用和原理

 

這個SpringFactoriesLoader就有一個類似的SPI機制,會去加載META-INF下定義的類,因為這邊源碼比較長,但是并不是很難理解,我就貼下一個全局的類加載路徑,大家基本上看一下也就能懂~

10分鐘搞懂SpringBoot的組件EnvironmentPostProcessor使用和原理

SPI的類加載路徑

好了,到此為止,整個分析也就結束了,基本上還是很簡單的

小結

本小節其實是為了簡介nacos整個spring boot源碼講解的一個鋪墊,但是單獨使用一個小節,也是合理的,EnvironmentPostProcessor組件在整個spring boot的生態中還是比較重要的,如果吧spring boot最后運行成功,比如一個機器人,那么EnvironmentPostProcessor組件就是開始組裝這個機器人之前存放零件的倉庫,以后缺什么組件都可以在這個容器中尋找~

分享到:
標簽:SpringBoot
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定