Spring的核心思想之DI:详解Spring DI循环依赖实现机制
IOC与DI是一个事物不同的两面,在Spring的核心思想之IOC:仿Spring自定义一个实现IOC的容器中对自动注入有了一个初步的了解。Springs中真实的DI是如何实现的呢?一个对象引用另一个对象递归注入属性即可实现后续的实例化,同时如果两个或者两个以上的 Bean 互相持有对⽅(Spring的核心思想之IOC:仿Spring自定义一个实现IOC的容器中就没有实现这个功能),最终形成闭环即所谓的循环依赖又如何实现属性的互相注入呢?
Spring bean生命周期具体流程如下:
实际与bean实例化及初始化相关的流程如下(单例模式,其他模式不支持循环依赖):
可以看到三级缓存保存的value其实是一个 Lambda 表达式 ObjectFactory。
在DefaultSingletonBeanRegistry类中提供获得单例bean的方法getSingleton:判断条件中有一条isSingletonCurrentlyInCreation(beanName),就是判断是否循环依赖。
对于Spring循环依赖使用三级缓存实现:一级缓存singletonObjects,存储单例对象bean已经经历了完整生命周期的 Bean;二级缓存earlySingletonObjects(防止循环依赖),存储 singletonObject,这个 Bean 实例化了,还没有初始化完全;三级singletonFactories,存储 singletonFactory——只是一个表达式,使用它之后就会保存结果到二级缓存同时删除此缓存中该表达式。
总结: 1)Spring 不⽀持原型 bean 的循环依赖。
2)单例bean通过setXxx或者@Autowired进⾏循环依赖
Spring 的循环依赖的理论依据基于 Java 的引⽤传递,当获得对象的引⽤时,对象的属性是可以延后设置的,但是构造器必须是在获取引⽤之前。Spring通过setXxx或者@Autowired⽅法解决循环依赖其实是通过提前暴露⼀个ObjectFactory对象来完成的。
现在有个问题是:在populateBean()方法之前为什么使用三级缓存保存一个关于待创建bean的 Lambda 表达式,从上图看直接实例化bean保存在二级缓存中不是更简单明了的解决循环依赖的问题么?这就涉及到Spring的另一大核心思想——AOP。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?