擼了一個簡易的配置中心,順帶整合到了SpringCloud( 三 )


說的簡單點就是用來定位到(也就是獲取的意思)項目啟動所需要的屬性信息 。同時要注意到括號內的 可能是遠程 告訴我們一個很重要的信息 , 那就是獲取的配置信息不僅僅可以存在本地,而且還可以存在遠程 。
遠程?作者這里就差直接告訴你可以從配置中心獲取了 。。
所以從這個注釋就可以發現,原來PropertySourceLocator就是起到在SpringCloud環境下從配置中心獲取配置的作用 。
PropertySourceLocator是一個接口 , 所以只要不同的配置中心實現這個接口,那么不同的配置中心就可以整合到了SpringCloud , 從而實現從配置中心加載配置屬性到Spring環境中了 。
2、如何實現注入到Bean中的屬性動態刷新?【擼了一個簡易的配置中心,順帶整合到了SpringCloud】上面講了在項目啟動的時候SpringCloud是如何從配置中心加載數據的,主要是通過新建一個容器,加載bootstrap配置文件和一些配置類 , 最后會調用PropertySourceLocator來從配置中心獲取到配置信息 。
那么在SpringCloud環境下,是如何實現注入到Bean中的屬性動態刷新的呢?
舉個例子

擼了一個簡易的配置中心,順帶整合到了SpringCloud

文章插圖
UserService
當在類上加一個@RefreshScope注解之后,那么當配置中心sanyou.username的屬性有變化的時候,那么此時注入的username也會跟著變化 。
這種變化是如何實現的呢?
SpringCloud中規定 , 當配置中心客戶端一旦感知到服務端的某個配置有變化的時候 , 需要發布一個RefreshEvent事件來告訴SpringCloud配置有變動 。

擼了一個簡易的配置中心,順帶整合到了SpringCloud

文章插圖
在SpringCloud中RefreshEventListener類會去監聽這個事件 , 一旦監聽到這個事件,就會進行兩步操作來刷新注入到對象的屬性 。

擼了一個簡易的配置中心,順帶整合到了SpringCloud

文章插圖
RefreshEventListener
  • 從配置中心再次拉取屬性值 , 而這個拉取的代碼邏輯跟項目啟動時拉取的屬性值核心邏輯幾乎是一樣的,也是創建一個新的spring容器,加載配置文件和配置類,最后通過PropertySourceLocator獲取屬性 , 這一部分核心的代碼邏輯是復用的 。
  • 有了最新的屬性之后,就開始刷新對象的屬性 。
刷新的邏輯實現的非常的巧妙,可不是你以為的簡單地將新的屬性重新注入對象中,而是通過動態代理的方式來實現的 。
對于在類上加了@RefreshScope注解的Bean,Spring在生成這個Bean的時候,會進行動態代理 。
這里我們就上面舉個UserService例子來分析,在生成UserService有兩步操作
  • 生成一個UserService對象,將從配置中心拉到的配置sanyou.username注入給UserService對象
  • 由于加了@RefreshScope,會給上一步驟生成的UserService對象進行代理,生成一個代理對象
最后真正暴露出去供我們使用的其實是就是這個代理對象,如圖所示

擼了一個簡易的配置中心,順帶整合到了SpringCloud

文章插圖
由于暴露出去的是一個代理對象,所以當調用getUsername方法的時候,其實是調用UserService的代理對象的getUsername方法,從而就會找到UserService,調用UserService的getUsername獲取到username的屬性值 。
當配置中心的配置有變動刷新屬性的時候,Spring會把UserService這個對象(非代理對象)給銷毀,重新創建一個UserService對象,注入最新的屬性值 。
當再次通過UserService代理對象獲取username屬性的時候,就會找最新創建的那個UserService對象,此時就能獲取到最新的屬性值 。

擼了一個簡易的配置中心,順帶整合到了SpringCloud

文章插圖
配置每刷新一次,UserService對象就會先銷毀再重新創建,但是暴露出去的UserService代理對象一直不會變 。
這樣,對于使用者來說,好像是UserService對象的屬性自動刷新了,其實本質上是UserService代理對象最終找的UserService對象發生了變化 。
到這應該就知道為什么加了@RefreshScope的對象能夠實現配置的自動刷新了,其實依靠的是動態代理完成的 。
3、源碼執行流程圖由于上面并沒有涉及整體執行流程的源碼分析 , 所以我特地結合源碼畫了兩張源碼的執行流程圖,有興趣的小伙伴可以對照著圖翻一翻具體的源碼 。
3.1啟動時加載配置流程

推薦閱讀