@RefreshScope(nacos配置熱更新方式)
@RefreshScope(nacos配置熱更新)
源碼分析
宏觀流程解析
1.spring對(duì)@RefreshScopre注解的bean做的事情
- 當(dāng)調(diào)用被@RefreshScope注解的bean的屬性的get方法時(shí) 則先從本地緩存里面獲取
- 當(dāng)本地緩存中 不存在當(dāng)前bean時(shí) 則重新創(chuàng)建 此時(shí) 會(huì)獲取 spring中最新環(huán)境配置
- 如果本地緩存中 存在當(dāng)前 bean則 直接返回對(duì)應(yīng)屬性值
2.nacos對(duì)@RefreshScopre注解的bean做的事情
- 當(dāng)配置更改時(shí) nacos服務(wù)端會(huì)發(fā)步一個(gè)配置已被更新事件
- 此時(shí) naocs客戶端 會(huì)接受到這個(gè)事件 接受到以后 會(huì)再在spring中發(fā)布環(huán)境配置刷新事件
- 然后 對(duì)應(yīng)的監(jiān)聽器 收到以后 則刷新spring環(huán)境配置 以及 清空本地緩存
源碼解析
@Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Scope("refresh") @Documented public @interface RefreshScope { /** * @see Scope#proxyMode() * @return proxy mode */ ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS; }
org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan
org.springframework.context.annotation.AnnotationConfigUtils#applyScopedProxyMode -->org.springframework.context.annotation.ScopedProxyCreator#createScopedProxy -->org.springframework.aop.scope.ScopedProxyUtils#createScopedProxy
org.springframework.cloud.context.scope.GenericScope#postProcessBeanDefinitionRegistry
org.springframework.cloud.context.scope.GenericScope.LockedScopedProxyFactoryBean#setBeanFactory
org.springframework.aop.scope.ScopedProxyFactoryBean#setBeanFactory
創(chuàng)建代理
------由上可知,被@RefreshScope注解的bean被包裝為一個(gè)
FactoryBean(org.springframework.cloud.context.scope.GenericScope.LockedScopedProxyFactoryBean)
由此調(diào)用時(shí)就會(huì)調(diào)用getObject()方法,這樣就會(huì)得到一個(gè)代理對(duì)象,執(zhí)行時(shí)會(huì)獲取到目標(biāo)對(duì)象 SimpleBeanTargetSource.getTarget(),以"scopedTarget."開頭的bean,接下來看一下該bean的創(chuàng)建時(shí)機(jī)
創(chuàng)建target
org.springframework.cloud.context.scope.refresh.RefreshScope#onApplicationEvent
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
org.springframework.cloud.context.scope.GenericScope#get
以上即@RefreshScope的相關(guān)對(duì)象的創(chuàng)建
由上可知,目標(biāo)類都會(huì)存于scope的cache里
NacosContextRefresher(nacos配置刷新)
public class NacosContextRefresher implements ApplicationListener<ApplicationReadyEvent>, ApplicationContextAware { public void onApplicationEvent(ApplicationReadyEvent event) { // many Spring context if (this.ready.compareAndSet(false, true)) { this.registerNacosListenersForApplications(); } } }
com.alibaba.cloud.nacos.refresh.NacosContextRefresher#registerNacosListenersForApplications --->com.alibaba.cloud.nacos.refresh.NacosContextRefresher#registerNacosListener
注冊(cè)監(jiān)聽器,監(jiān)聽nacos配置變化,并發(fā)布RefreshEvent
org.springframework.cloud.endpoint.event.RefreshEventListener#onApplicationEvent
org.springframework.cloud.context.refresh.ContextRefresher#refresh
1.刷新了環(huán)境,2清空cache
首先刷新環(huán)境
如下,有個(gè)前后對(duì)比,關(guān)鍵就在addConfigFilesToEnvironment()
首先copyEnvironment,雖說是copy,這里只保留了一些最基本的配置,如下
第二步,創(chuàng)建Spring容器 capture = builder.run();
這里還是走之前的邏輯,具體可參考
只是這次創(chuàng)建的兩個(gè)Spring容器都為AnnotationConfigApplicationContext,并且用完就關(guān)了
我們看一下方法執(zhí)行之后的environment
之后的邏輯就是對(duì)比兩個(gè)環(huán)境進(jìn)行替換了,這就是刷新環(huán)境的大致流程
然后清空cache
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
JavaEE的進(jìn)程,線程和創(chuàng)建線程的5種方式詳解
這篇文章主要為大家詳細(xì)介紹了JavaEE的進(jìn)程,線程和創(chuàng)建線程的5種方式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-03-03Java中Set集合轉(zhuǎn)為List集合常見的兩種方式
List是Java中比較常用的集合類,指一系列存儲(chǔ)數(shù)據(jù)的接口和類,可以解決復(fù)雜的數(shù)據(jù)存儲(chǔ)問題,這篇文章主要給大家介紹了關(guān)于Java中Set集合轉(zhuǎn)為List集合常見的兩種方式,需要的朋友可以參考下2023-12-12基于SpringBoot整合SSMP案例(開啟日志與分頁查詢條件查詢功能實(shí)現(xiàn))
這篇文章主要介紹了基于SpringBoot整合SSMP案例(開啟日志與分頁查詢條件查詢功能實(shí)現(xiàn)),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋參考下吧2023-11-11Java面試題沖刺第十三天--數(shù)據(jù)庫(3)
這篇文章主要為大家分享了最有價(jià)值的三道數(shù)據(jù)庫面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,感興趣的小伙伴們可以參考一下2021-07-07java web項(xiàng)目實(shí)現(xiàn)文件下載實(shí)例代碼
現(xiàn)在項(xiàng)目里面有個(gè)需求,需要把系統(tǒng)產(chǎn)生的日志文件給下載到本地 先獲取所有的日志文件列表,顯示到界面,選擇一個(gè)日志文件,把文件名傳到后臺(tái)2013-09-09打開.properties中文顯示unicode編碼問題以及解決
這篇文章主要介紹了打開.properties中文顯示unicode編碼問題以及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01Spring集成MyBatis?及Aop分頁的實(shí)現(xiàn)代碼
這篇文章主要介紹了Spring集成MyBatis?及Aop分頁的實(shí)現(xiàn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-04-04Windows Zookeeper安裝過程及啟動(dòng)圖解
這篇文章主要介紹了Windows Zookeeper安裝過程及啟動(dòng)圖解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-12-12SpringBoot實(shí)現(xiàn)短信發(fā)送及手機(jī)驗(yàn)證碼登錄
本文主要介紹了SpringBoot實(shí)現(xiàn)短信發(fā)送及手機(jī)驗(yàn)證碼登錄,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07