Spring Cloud動態配置刷新RefreshScope使用示例詳解
引言
用過Spring Cloud的同學都知道在使用動態配置刷新的我們要配置一個 @RefreshScope,在類上才可以實現對象屬性的的動態更新。
@RefreshScope 能實現動態刷新全仰仗著 @Scope這個註解。
一、瞭解@RefreshScope,先要瞭解@Scope
1、RefreshScope繼承於GenericScope, 而GenericScope實現瞭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是單例的。(默認) * prototype 表示該bean是多例的,即每次使用該bean時都會新建一個對象。 * request 在一次http請求中,一個bean對應一個實例。 * session 在一個httpSession中,一個bean對應一個實例 */ @AliasFor("value") String scopeName() default ""; /** * DEFAULT 不使用代理。(默認) * 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 的實現原理
1、@RefreshScope的實現
@Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Scope("refresh") @Documented public @interface RefreshScope { /** * @see Scope#proxyMode() */ ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS; }
可以看出它使用的就是 @Scope,其內部就一個屬性默認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)這個方法幫助我們來創建一個新的bean,也就是說 @RefreshScope在調用刷新的時候會使用get方法來給我們創建新的對象,這樣就可以通過spring的裝配機制將屬性重新註入瞭,也就實現瞭所謂的動態刷新。
2、GenericScope
幫我們實現瞭Scope
最重要的 get(String name, ObjectFactory<?> objectFactory)
方法,在GenericScope 裡面 包裝瞭一個內部類 BeanLifecycleWrapperCache
來對加瞭 @RefreshScope 從而創建的對象進行緩存,使其在不刷新時獲取的都是同一個對象。
public class GenericScope implements Scope, BeanFactoryPostProcessor...{ @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { beanFactory.registerScope(this.name/*refresh*/, this/*RefreshScope*/); ... } }
三、使用——@RefreshScope 使用流程
1、需要動態刷新的類標註@RefreshScope註解
2、@RefreshScope 註解標註瞭@Scope 註解,並默認瞭ScopedProxyMode.TARGET_CLASS; 屬性,此屬性的功能就是在創建一個代理,在每次調用的時候都用它來調用GenericScope get 方法來獲取對象
3、如屬性發生變更會調用 ContextRefresher refresh() -》RefreshScope refreshAll() 進行緩存清理方法調用,並發送刷新事件通知 -》 GenericScope 真正的 清理方法destroy() 實現清理緩存
4、在下一次使用對象的時候,會調用GenericScope get(String name, ObjectFactory<?> objectFactory) 方法創建一個新的對象,並存入緩存中,此時新對象因為Spring 的裝配機制就是新的屬性瞭。
以上就是Spring Cloud動態配置刷新RefreshScope使用示例詳解的詳細內容,更多關於RefreshScope配置刷新的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- 解決啟用 Spring-Cloud-OpenFeign 配置可刷新項目無法啟動的問題
- Spring之什麼是ObjectFactory?什麼是ObjectProvider?
- 關於Spring BeanPostProcessor的執行順序
- @RefreshScope 自動刷新配置文件的實例講解
- Spring Boot 條件註解詳情