老熟女激烈的高潮_日韩一级黄色录像_亚洲1区2区3区视频_精品少妇一区二区三区在线播放_国产欧美日产久久_午夜福利精品导航凹凸

重慶分公司,新征程啟航

為企業(yè)提供網站建設、域名注冊、服務器等服務

SpringCloud中@RefreshScope的原理是什么

本篇文章為大家展示了Spring Cloud中@RefreshScope的原理是什么,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

創(chuàng)新互聯(lián)專注于永年網站建設服務及定制,我們擁有豐富的企業(yè)做網站經驗。 熱誠為您提供永年營銷型網站建設,永年網站制作、永年網頁設計、永年網站官網定制、微信小程序開發(fā)服務,打造永年網絡公司原創(chuàng)品牌,更為您提供永年網站排名全網營銷落地服務。

@RefreshScope那些事

要說清楚RefreshScope,先要了解Scope

  • Scope(org.springframework.beans.factory.config.Scope)是Spring 2.0開始就有的核心的概念

  • RefreshScope(org.springframework.cloud.context.scope.refresh)是spring cloud提供的一種特殊的scope實現(xiàn),用來實現(xiàn)配置、實例熱加載。

  • Scope -> GenericScope -> RefreshScope

Spring Cloud中@RefreshScope的原理是什么

Scope與ApplicationContext生命周期

AbstractBeanFactory#doGetBean創(chuàng)建Bean實例

 protected  T doGetBean(...){
  final RootBeanDefinition mbd = ...
  if (mbd.isSingleton()) {
    ...
  } else if (mbd.isPrototype())
    ...
  } else {
     String scopeName = mbd.getScope();
     final Scope scope = this.scopes.get(scopeName);
     Object scopedInstance = scope.get(beanName, new ObjectFactory() {...});
     ...
  }
  ...
 }

Singleton和Prototype是硬編碼的,并不是Scope子類。 Scope實際上是自定義擴展的接口

Scope Bean實例交由Scope自己創(chuàng)建,例如SessionScope是從Session中獲取實例的,ThreadScope是從ThreadLocal中獲取的,而RefreshScope是在內建緩存中獲取的。

@Scope 對象的實例化

@RefreshScope 是scopeName="refresh"的 @Scope

 ...
 @Scope("refresh")
 public @interface RefreshScope {
   ...
 }

@Scope 的注冊 AnnotatedBeanDefinitionReader#registerBean

 public void registerBean(...){
  ...
  ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
   abd.setScope(scopeMetadata.getScopeName());
  ...
   definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
 }

讀取@Scope元數(shù)據(jù), AnnotationScopeMetadataResolver#resolveScopeMetadata

public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
     AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(
         annDef.getMetadata(), Scope.class);
     if (attributes != null) {
       metadata.setScopeName(attributes.getString("value"));
       ScopedProxyMode proxyMode = attributes.getEnum("proxyMode");
       if (proxyMode == null || proxyMode == ScopedProxyMode.DEFAULT) {
         proxyMode = this.defaultProxyMode;
       }
       metadata.setScopedProxyMode(proxyMode);
     }
}

Scope實例對象通過ScopedProxyFactoryBean創(chuàng)建,其中通過AOP使其實現(xiàn)ScopedObject接口,這里不再展開

現(xiàn)在來說說RefreshScope是如何實現(xiàn)配置和實例刷新的

RefreshScope注冊

RefreshAutoConfiguration#RefreshScopeConfiguration

 @Component
 @ConditionalOnMissingBean(RefreshScope.class)
 protected static class RefreshScopeConfiguration implements BeanDefinitionRegistryPostProcessor{
 ...
   registry.registerBeanDefinition("refreshScope",
   BeanDefinitionBuilder.genericBeanDefinition(RefreshScope.class)
             .setRole(BeanDefinition.ROLE_INFRASTRUCTURE)
             .getBeanDefinition());
 ...
 }

RefreshScope extends GenericScope, 大部分邏輯在 GenericScope 中

GenericScope#postProcessBeanFactory 中向AbstractBeanFactory注冊自己

public class GenericScope implements Scope, BeanFactoryPostProcessor...{
   @Override
   public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
     throws BeansException {
     beanFactory.registerScope(this.name/*refresh*/, this/*RefreshScope*/);
     ...
   }
}

RefreshScope 刷新過程

入口在ContextRefresher#refresh

 refresh() {
   Map before = ①extract(
       this.context.getEnvironment().getPropertySources());
   ②addConfigFilesToEnvironment();
   Set keys = ④changes(before,
       ③extract(this.context.getEnvironment().getPropertySources())).keySet();
   this.context.⑤publishEvent(new EnvironmentChangeEvent(keys));
   this.scope.⑥refreshAll();
 }

①提取標準參數(shù)(SYSTEM,JNDI,SERVLET)之外所有參數(shù)變量
②把原來的Environment里的參數(shù)放到一個新建的Spring Context容器下重新加載,完事之后關閉新容器
③提起更新過的參數(shù)(排除標準參數(shù))
④比較出變更項
⑤發(fā)布環(huán)境變更事件,接收:EnvironmentChangeListener/LoggingRebinder
⑥RefreshScope用新的環(huán)境參數(shù)重新生成Bean
重新生成的過程很簡單,清除refreshscope緩存幷銷毀Bean,下次就會重新從BeanFactory獲取一個新的實例(該實例使用新的配置)

RefreshScope#refreshAll

 public void refreshAll() {
     super.destroy();
     this.context.publishEvent(new RefreshScopeRefreshedEvent());
 }
GenericScope#destroy
 public void destroy() {
   ...
   Collection wrappers = this.cache.clear();
   for (BeanLifecycleWrapper wrapper : wrappers) {
     wrapper.destroy();
   }
 }

Spring Cloud Bus 如何觸發(fā) Refresh

BusAutoConfiguration#BusRefreshConfiguration 發(fā)布一個RefreshBusEndpoint

@Configuration
 @ConditionalOnClass({ Endpoint.class, RefreshScope.class })
 protected static class BusRefreshConfiguration {

   @Configuration
   @ConditionalOnBean(ContextRefresher.class)
   @ConditionalOnProperty(value = "endpoints.spring.cloud.bus.refresh.enabled", matchIfMissing = true)
   protected static class BusRefreshEndpointConfiguration {
     @Bean
     public RefreshBusEndpoint refreshBusEndpoint(ApplicationContext context,
         BusProperties bus) {
       return new RefreshBusEndpoint(context, bus.getId());
     }
   }
 }

RefreshBusEndpoint 會從http端口觸發(fā)廣播RefreshRemoteApplicationEvent事件

 @Endpoint(id = "bus-refresh")
 public class RefreshBusEndpoint extends AbstractBusEndpoint {
    public void busRefresh() {
     publish(new RefreshRemoteApplicationEvent(this, getInstanceId(), null));
   }
 }

BusAutoConfiguration#refreshListener 負責接收事件(所有配置bus的節(jié)點)

 @Bean
 @ConditionalOnProperty(value = "spring.cloud.bus.refresh.enabled", matchIfMissing = true)
 @ConditionalOnBean(ContextRefresher.class)
 public RefreshListener refreshListener(ContextRefresher contextRefresher) {
   return new RefreshListener(contextRefresher);
 }

RefreshListener#onApplicationEvent 觸發(fā) ContextRefresher

public void onApplicationEvent(RefreshRemoteApplicationEvent event) {
   Set keys = contextRefresher.refresh();
 }

大部分需要更新的服務需要打上@RefreshScope, EurekaClient是如何配置更新的

EurekaClientAutoConfiguration#RefreshableEurekaClientConfiguration

 @Configuration
 @ConditionalOnRefreshScope
 protected static class RefreshableEurekaClientConfiguration{
   @Bean
   @RefreshScope
   public EurekaClient eurekaClient(...) {
     return new CloudEurekaClient(manager, config, this.optionalArgs,
         this.context);
   }
   
   @Bean
   @RefreshScope
   public ApplicationInfoManager eurekaApplicationInfoManager(...) {
     ...
     return new ApplicationInfoManager(config, instanceInfo);
   }
 }

上述內容就是Spring Cloud中@RefreshScope的原理是什么,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注創(chuàng)新互聯(lián)行業(yè)資訊頻道。


網站題目:SpringCloud中@RefreshScope的原理是什么
標題網址:http://www.xueling.net.cn/article/iejhsj.html 主站蜘蛛池模板: 黑人30厘米少妇高潮全部进入 | 中文大字幕mm播放 | 久久精品女人天堂av免费观看 | 国产精品久久久aaa 好湿好紧太硬了我太爽了视频 | 午夜嘿嘿| 五月婷婷狠狠干 | 日本欧美一区二区三区在线播 | 99久久久久成人国产免费 | 国产婷婷色一区二区三区四区 | 成年人视频在线看 | 国内午夜国产精品小视频 | 国产网站视频 | 亚洲新视频 | 乌克兰少妇大胆大BBW | 欧美高潮又爽又黄又硬又无遮 | 成人淫片 | 中文字幕在线日本 | 热久久精品国产 | 国内嫩模私拍精品视频 | japanese佳佳丝袜足调教 | 日本人妻japanesexxxx | 国产一区视频在线 | 国产精品沙发系列 | 国产熟妇勾子乱视频 | 日本中文一区二区三区亚洲 | 国产特级毛片AAAAAA高潮流水 | 中文字幕亚洲制服在线看 | 精品国产一级毛片 | 91福利视频在线观看 | 亚洲国产天堂久久久久久 | 亚洲国产精品VA在线观看黑人 | 乱h好大噗嗤噗嗤烂了 | 日韩入口 | av2014天堂网| 亚洲AV无码一区二区三区天堂 | 女人体1963毛片a级 | 激情久久一区二区三区 | 欧美精品网站 | 免费观看a视频 | 国产成人精品久久一区二区三区 | 女性裸体啪啪无遮挡免费网站 |