美文网首页springcloudJava
Spring Cloud @RefreshScope 原理分析:

Spring Cloud @RefreshScope 原理分析:

作者: 互联网高级架构师 | 来源:发表于2023-02-24 13:24 被阅读0次

前面我们知道,被 @RefreshScope 注解的实例,在扫描生成 BeanDefiniton 时,被偷龙转凤了:注册了两个 Bean 定义,一个 beanName 同名、类型是 LockedScopedProxyFactoryBean.class 代理工厂 Bean,一个 scopedTarget.beanName 的目标 Bean。

当程序使用 getBean 获取一个被 @RefreshScope 注解的实例时,容器返回的是一个JdkDynamicAopProxy 代理对象, 它是怎么从 ScopedProxyFactoryBean 创建的呢?本文记录这个过程的跟踪流程。

代理类的创建

首先,从 spring 的抽象 Bean 工厂类 AbstractApplicationContext 开始,当 getBean(type) 调用时,开启 Bean 工厂生产的流程:

接着,它背后是 DefaultListableFactoryBean,开始干活,resolveBean 返回需要的 Bean 实例:

继续跟resolveNamedBean,定位到背后的 Bean Definition :

注意,这里在查找候选类型的时候,由于扫描时注入了两个相同类型的 Bean

注意这里,还记得吗,代理类和委托类类型相同,candidateNames 返回了两个名称 beanName 和 scopedTarget.beanName,但是真正委托类的属性被修改了,这里只会得到一个名称:

一路委托调用

终于到了真正干活的地方 doGetBean

  1. 先查找 beanName 所在的单例对象,实际就是 ScopedProxyFactoryBean 对象;
  2. 接着调用 getObjectForBeanInstance 创建实例。

核心代码到了DefaultSingletonBeanRegistry.getSingleton,它开始查找 beanName 所在的单例工厂:

接着回到 AbstractBeanFactory.getObjectForBeanInstance 开始从单例工厂创建实例:

因为前一步取到的是 ScopedProxyFactoryBean 的实例是一个 FactoryBean,所以直接进入最后一个分支:

doGetObjectFromFactoryBean 调用 ScopedProxyFactoryBean.getObject

所以这个调用链,最终返回了 ScopedProxyFactoryBean 在被注入 BeanFactory 时创建的那个 proxy 代理类:

启示录

当程序使用 getBean 获取一个被 @RefreshScope 注解的实例时,最终得到的是 LockedScopedProxyFactoryBeangetObject() 返回值,它是一个 JdkDynamicAopProxy 代理对象。

中间对 ScopedProxyFactoryBean 初始化的流程,含有很多细节,比如 GenericScoped 注册的 BeanDefinitionRegistryPostProcessor 对代理 Bean 定义添加了一个构造函数的参数,它是怎么在 LockedScopedProxyFactoryBean 初始化时使用的。

还有 AbstractAutowiredCapableBeanFactory 的织入回调 invokeAwareMethodBeanDefinitionRegistryPostProcessor 回调用等,水不知几深,浅尝则止尔!

作者:毕小宝
链接:https://juejin.cn/post/7203749658530332731
来源:稀土掘金

相关文章

网友评论

    本文标题:Spring Cloud @RefreshScope 原理分析:

    本文链接:https://www.haomeiwen.com/subject/frrxldtx.html