Spring Cloud動態(tài)配置刷新RefreshScope使用示例詳解
引言
用過Spring Cloud的同學(xué)都知道在使用動態(tài)配置刷新的我們要配置一個 @RefreshScope,在類上才可以實(shí)現(xiàn)對象屬性的的動態(tài)更新。
@RefreshScope 能實(shí)現(xiàn)動態(tài)刷新全仰仗著 @Scope這個注解。
一、了解@RefreshScope,先要了解@Scope
1、RefreshScope繼承于GenericScope, 而GenericScope實(shí)現(xiàn)了Scope接口。
2、@Scope代表了Bean的作用域,我們來看下其中的屬性:
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Scope { /** * Alias for {@link #scopeName}. * @see #scopeName */ @AliasFor("scopeName") String value() default ""; /** * singleton 表示該bean是單例的。(默認(rèn)) * prototype 表示該bean是多例的,即每次使用該bean時都會新建一個對象。 * request 在一次http請求中,一個bean對應(yīng)一個實(shí)例。 * session 在一個httpSession中,一個bean對應(yīng)一個實(shí)例 */ @AliasFor("value") String scopeName() default ""; /** * DEFAULT 不使用代理。(默認(rèn)) * NO 不使用代理,等價于DEFAULT。 * INTERFACES 使用基于接口的代理(jdk dynamic proxy)。 * TARGET_CLASS 使用基于類的代理(cglib)。 */ ScopedProxyMode proxyMode() default ScopedProxyMode.DEFAULT; }
3、@RefreshScope等同于scopeName="refresh"的@Scope:
@Scope("refresh") public @interface RefreshScope { ... }
二、RefreshScope 的實(shí)現(xiàn)原理
1、@RefreshScope的實(shí)現(xiàn)
@Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Scope("refresh") @Documented public @interface RefreshScope { /** * @see Scope#proxyMode() */ ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS; }
可以看出它使用的就是 @Scope,其內(nèi)部就一個屬性默認(rèn)ScopedProxyMode.TARGET_CLASS。那我們來看下Scope這個接口:
public interface Scope { Object get(String name, ObjectFactory<?> objectFactory); @Nullable Object remove(String name); void registerDestructionCallback(String name, Runnable callback); @Nullable Object resolveContextualObject(String key); @Nullable String getConversationId(); }
主要看看Object get(String name, ObjectFactory<?> objectFactory)這個方法幫助我們來創(chuàng)建一個新的bean,也就是說 @RefreshScope在調(diào)用刷新的時候會使用get方法來給我們創(chuàng)建新的對象,這樣就可以通過spring的裝配機(jī)制將屬性重新注入了,也就實(shí)現(xiàn)了所謂的動態(tài)刷新。
2、GenericScope
幫我們實(shí)現(xiàn)了Scope
最重要的 get(String name, ObjectFactory<?> objectFactory)
方法,在GenericScope 里面 包裝了一個內(nèi)部類 BeanLifecycleWrapperCache
來對加了 @RefreshScope 從而創(chuàng)建的對象進(jìn)行緩存,使其在不刷新時獲取的都是同一個對象。
public class GenericScope implements Scope, BeanFactoryPostProcessor...{ @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { beanFactory.registerScope(this.name/*refresh*/, this/*RefreshScope*/); ... } }
三、使用——@RefreshScope 使用流程
1、需要動態(tài)刷新的類標(biāo)注@RefreshScope注解
2、@RefreshScope 注解標(biāo)注了@Scope 注解,并默認(rèn)了ScopedProxyMode.TARGET_CLASS; 屬性,此屬性的功能就是在創(chuàng)建一個代理,在每次調(diào)用的時候都用它來調(diào)用GenericScope get 方法來獲取對象
3、如屬性發(fā)生變更會調(diào)用 ContextRefresher refresh() -》RefreshScope refreshAll() 進(jìn)行緩存清理方法調(diào)用,并發(fā)送刷新事件通知 -》 GenericScope 真正的 清理方法destroy() 實(shí)現(xiàn)清理緩存
4、在下一次使用對象的時候,會調(diào)用GenericScope get(String name, ObjectFactory<?> objectFactory) 方法創(chuàng)建一個新的對象,并存入緩存中,此時新對象因?yàn)镾pring 的裝配機(jī)制就是新的屬性了。
以上就是Spring Cloud動態(tài)配置刷新RefreshScope使用示例詳解的詳細(xì)內(nèi)容,更多關(guān)于RefreshScope配置刷新的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Spring IOC源碼剖析_如何整體認(rèn)知Spring體系結(jié)構(gòu)
這篇文章主要介紹了Spring IOC源碼剖析_如何整體認(rèn)知Spring體系結(jié)構(gòu)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09解決feignClient調(diào)用時獲取返回對象類型匹配的問題
這篇文章主要介紹了解決feignClient調(diào)用時獲取返回對象類型匹配的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06Java實(shí)現(xiàn)房屋出租系統(tǒng)詳解
這篇文章主要介紹了實(shí)現(xiàn)Java房屋出租系統(tǒng)的實(shí)現(xiàn)過程,文章條理清晰,在實(shí)現(xiàn)過程中加深了對相關(guān)概念的理解,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-10-10Java使用CompletableFuture進(jìn)行非阻塞IO詳解
這篇文章主要介紹了Java使用CompletableFuture進(jìn)行非阻塞IO詳解,CompletableFuture是Java中的一個類,用于支持異步編程和處理異步任務(wù)的結(jié)果,它提供了一種方便的方式來處理異步操作,并允許我們以非阻塞的方式執(zhí)行任務(wù),需要的朋友可以參考下2023-09-09詳解關(guān)于SpringBoot的外部化配置使用記錄
這篇文章主要介紹了詳解關(guān)于SpringBoot的外部化配置使用記錄,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05