Spring Cloud @RefreshScope 原理分析:扫描 Bean 定义

Posted 毕小宝

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Cloud @RefreshScope 原理分析:扫描 Bean 定义相关的知识,希望对你有一定的参考价值。

背景

最近读了一下 spring cloud 的 @RefreshScope 生效的源码,总结一下该注解的 refresh 类型的类实例化的过程。

关键技术点:

  1. 扫描过程中对 @RefreshScope 注解做了特殊处理,会额外注册两个BeanDefinition
  2. GenericScope 实现了 BeanDefinitionRegistryPostProcessor 接口,并对 refresh 的 BeanDefinition 添加了构造函数参数为自己,同时设置 beanClass 属性为 GenericScope.LockedScopedProxyFactoryBean.class,合成属性为 true
  3. GenericScope.LockedScopedProxyFactoryBean 类实现了 FactoryBeanBeanFactoryAwareMethodInterceptor 接口。

拆解三个部分:扫描 Bean 定义、代理类实例化、代理类方法调用,从这三个过程的源码,来理解为什么 @RefreshScope 标注的类的实能够动态应对环境变量的变化。

原始扫描 Bean 定义过程

ClassPathBeanDefinitionScanner 扫描时会对 @RefreshScope 注解的类的 BeanDefinition 定义信息作两个操作:

这个 applyScopedProxyMode 方法判断当前代理模式,如果

@RefreshScope 的这个属性是 ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS ,即针对这类注解的类在扫描时,会额外创建代理类的 BeanDefinition

主要是三个操作:

  1. 以原始的 BeanDefinition 新建一个代理类的 RootBeanDefinition,并且设置它的 decoratedDefinition 为原始对象,代理类的类型为 ScopedProxyFactoryBean
  2. 再注册一个以 "scopedTarget." + originalBeanName ,基于原始配置的目标定义,即真正实体的定义修改了;
  3. 最后再注册一个用 originalBeanName 的代理类的定义,就是偷梁换柱,完全代理了目标对象。
  4. 原始类定义的 autowireCandidate 为 false ,primary 也为 false ,那么就能保证实力获取时优先找到的候选对象是代理对象。

GenericScope 增强注册

GenericScope 实现了 BeanDefinitionRegistryPostProcessor 接口,而且它 Order 优先级较低,保证在 第一步的扫描之后执行如下操作:

这里对扫描阶段创建的代理类的 BeanDefinition 作了三个增强:

  1. 修改代理的 BeanDefinition 类型为自己的 LockedScopedProxyFactoryBean
  2. 为代理类的 BeanDefinition 添加一个构造函数的参数值为自己,因为 LockedScopedProxyFactoryBean 类的构造函数需要一个入参 Scope
  3. 设置合成属性为真。

启示录

@RefreshScope 是 spring cloud 的技术,它本质上扩展了 spring 框架的 Scope,跟其他单例、原型、请求类型、会话类型一样,是一种扩展 Scope ,巧妙应用了 ScopedProxyMode.TARGET_CLASS 和 AOP ,把 refresh 类型的对象托管起来,保证环境变量变更时,销毁旧的实例、获取最新的实例。

下一篇讲继续总结 ScopedProxyFactoryBean 这个类是如何创建出 @RefreshScope 注解的实例的,为什么能将一个委托类型偷梁换柱为一个 JdkDynamicAopProxy 代理类。

以上是关于Spring Cloud @RefreshScope 原理分析:扫描 Bean 定义的主要内容,如果未能解决你的问题,请参考以下文章

spring-cloud-config-server

Spring Cloud实战Spring Cloud GateWay服务网关

spring-cloud-config——Quick Start

Spring Cloud入门 - Spring Cloud保护机制

spring cloud 与 spring boot 和 spring cloud alibab 版本号对应

整合spring cloud云服务架构 - Spring Cloud简介