循环依赖如何产生
在spring容器中,如果两个或者多个Bean互相依赖对方(如:A依赖B,B又依赖A),就会形成循环依赖,如果没有特殊处理那么这样就会导致无限循环,因为每个Bean都要等待对方完成初始化才能完成自己的初始化。
解决方案-提前暴露
下图是spring中Bean的生命周期
具体实现:
三级缓存
1.一级缓存(singleton Object):存放已经完成初始化的Bean实例。这个缓存在Bean完全初始化后使用。
2.二级缓存(Early Singleton Object):存放原始的Bean实例或者AOP对象(通过三级缓存的一个lambda方法判断获取原始对象还是AOP对象),即已经创建但尚未填充属性的Bean。这个缓存允许Bean在属性填充阶段被其他Bean引用。
3.三级缓存(Singleton Factories):存放Bean工厂对象(ObjectFactory),用户创建Bean的早期引用,在实例化Bean时就放入三级缓存一个lambda表达式。
总结:
1.实例化
此时记录正在初始化Bean,并且将FactroyObject(存在一个获取当前普通bean还是获取AOPbean逻辑)放入三级缓存
2.填充属性
填充其他属性,如果有循环依赖(根据实例化时记录的是否正在实例化的标志判断),去二级缓存找,如果未找到,去三级缓存找,获取bean后放入二级缓存
3.填充其他属性
4.其他步骤,包括AOP
有循环依赖的这步应该是取二级缓存或者跳过
5.加入单例池
有循环依赖的 二级缓存放入单例池