likes
comments
collection
share

Spring Cloud @RefreshScope 原理分析:代理类的创建

作者站长头像
站长
· 阅读数 17

背景

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

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

代理类的创建

首先,从 spring 的抽象 Bean 工厂类 AbstractApplicationContext 开始,当 getBean(type) 调用时,开启 Bean 工厂生产的流程: Spring Cloud @RefreshScope 原理分析:代理类的创建 接着,它背后是 DefaultListableFactoryBean,开始干活,resolveBean 返回需要的 Bean 实例: Spring Cloud @RefreshScope 原理分析:代理类的创建 继续跟resolveNamedBean,定位到背后的 Bean Definition : Spring Cloud @RefreshScope 原理分析:代理类的创建 注意,这里在查找候选类型的时候,由于扫描时注入了两个相同类型的 Bean Spring Cloud @RefreshScope 原理分析:代理类的创建 注意这里,还记得吗,代理类和委托类类型相同,candidateNames 返回了两个名称 beanName 和 scopedTarget.beanName,但是真正委托类的属性被修改了,这里只会得到一个名称: Spring Cloud @RefreshScope 原理分析:代理类的创建 一路委托调用Spring Cloud @RefreshScope 原理分析:代理类的创建 Spring Cloud @RefreshScope 原理分析:代理类的创建 终于到了真正干活的地方 doGetBeanSpring Cloud @RefreshScope 原理分析:代理类的创建

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

核心代码到了DefaultSingletonBeanRegistry.getSingleton,它开始查找 beanName 所在的单例工厂: Spring Cloud @RefreshScope 原理分析:代理类的创建 接着回到 AbstractBeanFactory.getObjectForBeanInstance 开始从单例工厂创建实例: Spring Cloud @RefreshScope 原理分析:代理类的创建 因为前一步取到的是 ScopedProxyFactoryBean 的实例是一个 FactoryBean,所以直接进入最后一个分支: Spring Cloud @RefreshScope 原理分析:代理类的创建 doGetObjectFromFactoryBean 调用 ScopedProxyFactoryBean.getObjectSpring Cloud @RefreshScope 原理分析:代理类的创建 所以这个调用链,最终返回了 ScopedProxyFactoryBean 在被注入 BeanFactory 时创建的那个 proxy 代理类:

Spring Cloud @RefreshScope 原理分析:代理类的创建

启示录

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

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

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

参考

看到一篇很完整的文章,可以参考补充:《SpringCloud @RefreshScope动态刷新配置原理浅析》

转载自:https://juejin.cn/post/7203749658530332731
评论
请登录