当然是用三级缓存来解决循环依赖问题。
那二级缓存能解决吗?
首先我们要知道Spring bean的生命周期
1.实例化(new)
2.属性赋值(populate)
3.初始化 一堆钩子函数(动态代理的生成也在这一步)
先来看二级缓存
在A实例化完成后,开始属性赋值的时候,去缓存中找B,发现B没有完成初始化,就开始B的实例化,之后发现A并没有初始化完成,所以B要去拿到提前暴露的A的对象,之后B就可以顺利进行初始化,初始化完成后将B放入一级缓存,之后A就可以去以及缓存中拿B,A就可以顺利执行完,执行完后,A也将放入一级缓存中。
那既然二级缓存能解决,为什么要用到三级缓存呢?
如果A不是简单的A,它如果要用到动态代理怎么办?
先搞清楚一个点,一级缓存中存的是A还是A的代理对象?
A引用B,B也引用A,如果A有代理对象的话,那A的代理对象也会引用A,那一级缓存放的是A还是A的代理对象呢?
当然是A的代理对象,如果放的是A,别人从容器里拿出A,调用它的方法,那注解就不生效了。(代理模式只做增强,不做修改 在执行A的前后增加某些操作)
那既然一级缓存存储的是A的代理对象,那B要是从二级缓存中拿到了A的暴露单例Bean(这个时候,这里面还是A的原始对象,非代理对象),但是咱们要的是A的代理对象。那不是GG了嘛
既然二级缓存不行,下面我们来介绍一下三级缓存如何解决循环依赖问题。
首先A实例化完后,放入第三级缓存中,然后去创建B,B去一级缓存中去拿 ,一级缓存没有,去二级缓存拿,也没有如果去三级缓存中拿,那肯定不行,B要的是代理对象,所以要有个地方去存A的代理对象,代理对象放在第二级缓存中。