@RefreshScope那些事 - 简书
RefreshScope 也是Scope
Spring Cloud 2.2.2 源码之三十九nacos配置动态刷新原理一_王伟王胖胖的博客-CSDN博客_nacos动态刷新原理

Scope bean的创建

和Singleton Bean不同的是,在使用createBean() 创建Bean之后由scopes.get()来处理,而

  • Singleton是通过getSingleton()放入DefaultSingletonBeanRegistry#singletonObjects中
  • Scope Bean是存放在GenericScope#cache中
    • 每当调用RefreshScope#refresh就是调用GenericScope#destroy(java.lang.String)销毁缓存,然后发送一个RefreshScopeRefreshedEvent事件。
    • 下次使用,重新创建bean再放入缓存。 ```java // Create bean instance. if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try {
      1. return createBean(beanName, mbd, args);
      } catch (BeansException ex) {
      1. // Explicitly remove instance from singleton cache: It might have been put there
      2. // eagerly by the creation process, to allow for circular reference resolution.
      3. // Also remove any beans that received a temporary reference to the bean.
      4. destroySingleton(beanName);
      5. throw ex;
      } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); }

else if (mbd.isPrototype()) { // It’s a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); }

else { String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException(“No Scope registered for scope name ‘“ + scopeName + “‘“); } try { Object scopedInstance = scope.get(beanName, () -> { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, “Scope ‘“ + scopeName + “‘ is not active for the current thread; consider “ + “defining a scoped proxy for this bean if you intend to refer to it from a singleton”, ex); } } ```

ContextRefresher#refresh

image.png

addConfigFilesToEnvironment

  1. 在外部配置化文件的属性发生变化时,重新启动一个applicationContext的Spring容器
  2. 这个新的Spring容器会重新加载外部化配置属性,获取到最新的propertySources
  3. 将原Spring容器的propertySources与新的propertySources进行比较,并覆盖原Spring容器的旧属性值,完成属性的动态刷新
  4. 关闭新建的Spring容器。

image.png