循环依赖与spring的三级缓存

什么是循环依赖

它发生在一个Bean A依赖于另一个Bean b,而b反过来也依赖于a的情况。

比如下列情况:

 

当然可能不止这样,可能是A->B->C->D->E->A这样的循环依赖甚至更多

为了解决循环依赖,我们引入了二层缓冲和三层缓冲。

我们看下面的代码

@Service
public class TestService1 {

    @Autowired
    private TestService2 testService2;

    public void test1() {
    }
}

@Service
public class TestService2 {

    @Autowired
    private TestService1 testService1;

    public void test2() {
    }
}

他也是个循环依赖, 但在spring里没有问题,因为spring自己帮我们解决了这个问题。

Spring里的循环依赖

循环依赖出现于一下场景:

spring内部有三级缓存:

  • singletonObjects 一级缓存,用于保存实例化、注入、初始化完成的bean实例
  • earlySingletonObjects 二级缓存,用于保存实例化完成的bean实例
  • singletonFactories 三级缓存,用于保存bean创建工厂,以便于后面扩展有机会创建代理对象。

对于上面的代码(单例的setter注入),spring内部是这么实现的

而从图中看好像只需要一层三级缓存即可,那二层缓存为什么还需要存在呢?

这是因为,第三级缓存里保存的并非真正的实例对象,而是ObjectFactory对象。通过它创建的实例对象每次可能都不一样。如果没有二层缓存,那发生多次依赖调用,如1调用23,2调用1,3调用1,2已经访问过一次三级缓存了,等到3时,在访问一次ObjectFactory对象,那二者创建的可能不是同一个对象,就会出错。

针对这种场景spring是怎么做的呢?

我们查看源码,发现在AbstractAutowireCapableBeanFactorydoCreateBean方法的这段代码中有这一行代码:

它定义了一个匿名内部类,通过getEarlyBeanReference方法获取代理对象,其实底层是通过AbstractAutoProxyCreator类的getEarlyBeanReference生成代理对象。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值