面试回答--》
简单来说,主要是有三级缓存,在里面有发现循环依赖,就会临时放到二级缓存(earlySingletonObjects 表示有循环依赖的),最后都放到一级缓存(singletonObjects)里面去。
一级:singletonObjects、二级:earlySingletonObjects 、三级:singletonFactories
类A(属性B) .... 类B(属性A)
具体过程:
1.对象A一开始会放入三级缓存( singletonFactories),发现依赖B,也放入三级缓存; ------------------singletonFactories=A,B
2.开始注入B中的依赖A时,把A从三级移到二级(删除三级中A); -------------------------singletonFactories=B earlySingletonObjects=A
3.把B放进一级缓存,删除三级,完成B的注入;---------------------------singletonObjects=B earlySingletonObjects=A
4.把A也放入一级缓存,删除二级缓存,完成A的注入。至此A,B注入完成。 ------------------singletonObjects=A,B
理解:为什么不采用这种方式就会出现循环依赖?
我们知道spring的实例默认是单例的,singletonObjects存的就是单例池。比如说在实例化A的时候,发现有依赖B,会再实例化一个B,作为A的属性,再把B放入单例池。然后实例化B的时候,发现有依赖A,这个时候如果没有三级缓存,就会再创建另一个实例A,一直循环创建下去。三级缓存就解决了这个问题。