爱喝冬瓜汤的萝卜

导航

Spring的循环依赖

Spring的生命周期

  1. BeanDefinitaion
  2. 实例化
    3.属性注入
    4.Aware方法指向
    5.BeanPostProcessor.prePostPrecessor()
    6.InitializationBean接口指向
    8.init-method()指向
    9.BeanPostProcessor.postPostProcessor()
    10 指向destory-method()方法
  3. DisableBean方法

解决循环依赖

1.对于bean是非单例的无法解决循环依赖,因为无法缓存bean.

2.对于Constuctor类型创建bean导致的循环依赖无法解决.

3.对于单例的循环依赖的解决方式:

Spring bean在创建过程中有三种状态,分别存放在三个map的缓冲区中,第一个是 最终创建完成的;第二个是:增强完成,未注入完成;第三个是实例化完成以后的ObjectFactory.
4.a --> b --> a循环依赖的解决方式

  1. 创建a的示例 ObjectFactory 存放在 缓存三种
  2. 开始注入Bean B,发现Bean b没有
    3.开始初始化Bean B
  3. 将Bean B创建添加到 提前暴露的三级缓存
  4. 往Bean B中注入Bean A. 这个时候从以及缓存没有取到,二级缓存没有取到,到三级缓存取到了ObjectFactory然后进行执行,这里可能会得到一个增强的对象,然后讲对象放到 缓存二中,删除缓存三种的ObjectFatory
  5. 将Bean A 注入到BeanB中.bean B创建完成,放到 一级缓存中.
    7.继续注入BeanA,这个时候将 Bean B 注入到 BeanA中.完成注入
  6. 校验当前注入完成的Bean对象和二级缓存中的Bean对象是否相同,如果不同,抛出错误.原因是Aop的增强是通过Spring的BeanPostProcessor帮助生成的,生成的对象会被放置到到二级缓存中,可能有一些BeanPostProcessor生成了新的Bean,但是没有放置到二级缓存中,这样会导致AOP的失效..
    8.然后讲 Bean A从缓存2中移动到缓存1中.

为什么需要三级缓存?

因为三级缓存中定义了三种不同阶段的Bean的状态,第一阶段是生成ObjectFactory,第二阶段是是增强后的对象.第三阶段是:最终完成实例化的对象.
其中第二阶段是增强后的对象默认是从getEarlyBeanReference 这个方法中获取到的,但是有些其他的时候,可能使用其他的BeanPostProssor中的方法实现的.导致aop的增强的单例不唯一,所以会校验.
同时适用三个不同的缓存来表示缓存的三个不同的状态,本来也比较优秀.这样很容易阅读出对应的Bean从哪个map中读出来的.

posted on 2022-06-21 17:16  爱喝冬瓜汤的萝卜  阅读(28)  评论(0编辑  收藏  举报