首页 >文档 > spring解决循环依赖的原理

spring解决循环依赖的原理

Spring如何解决循环依赖?三级缓存机制是关键!本文深入解析Spring框架如何通过singletonObjects、earlySingletonObjects和singletonFactories三级缓存破解Bean循环依赖问题。详细讲解实例化、提前曝光、依赖注入的完整流程,特别说明为什么构造函数循环依赖无法解决。适合Java开发者学习Spring核心原理,也是面试高频考点。想系统掌握Spring技术?推荐《2025年Java面试宝典》最新版,助你轻松应对Spring框架相关面试题。

Spring解决循环依赖的原理

2025年Java面试宝典最新版已更新!
链接: https://pan.baidu.com/s/1RUVf75gmDVsg8MQp4yRChg?pwd=9b3g
提取码: 9b3g


什么是循环依赖?

循环依赖是指两个或多个Bean相互依赖,形成闭环。例如:Bean A依赖Bean B,同时Bean B又依赖Bean A。这种情况在Spring中会导致初始化失败吗?答案是不一定!Spring通过三级缓存机制巧妙地解决了部分循环依赖问题。

面试鸭返利网


Spring的解决思路

Spring的核心思路是提前暴露未完成初始化的对象。通过三级缓存的分阶段处理,将Bean的创建与依赖注入分离。具体步骤如下:

  1. 实例化:先通过构造器创建Bean的原始对象(此时对象属性未赋值)。
  2. 提前曝光:将原始对象存入三级缓存(singletonFactories)。
  3. 依赖注入:对Bean进行属性赋值,此时若发现依赖其他Bean,递归创建依赖对象。
  4. 最终初始化:完成所有依赖注入后,Bean进入完全可用状态。

三级缓存机制详解

Spring通过三个Map实现循环依赖的破解:

| 缓存名称 | 存储内容 | 作用 | |-------------------------|-----------------------------------|--------------------------------------| | singletonObjects | 初始化完成的Bean | 直接返回已完成的Bean | | earlySingletonObjects | 提前暴露的Bean(未完成属性注入) | 解决循环依赖的中间状态 | | singletonFactories | Bean工厂(用于生成原始对象) | 生成原始对象并存入二级缓存 |

流程示意图
面试鸭返利网


具体解决流程

以Bean A和Bean B相互依赖为例:

  1. 创建Bean A

    • 实例化A的原始对象,存入singletonFactories
    • 开始为A注入属性,发现依赖Bean B。
  2. 创建Bean B

    • 实例化B的原始对象,存入singletonFactories
    • 开始为B注入属性,发现依赖Bean A。
  3. 解决循环依赖

    • singletonFactories中获取A的原始对象,存入earlySingletonObjects
    • 将A的原始对象注入给B,B完成初始化。
    • 回到A的依赖注入流程,此时B已就绪,A完成初始化。

为什么构造函数循环依赖无法解决?

如果循环依赖是通过构造函数发生的(例如:A的构造函数需要B,B的构造函数需要A),Spring会直接抛出BeanCurrentlyInCreationException因为此时Bean还未实例化,无法提前暴露对象,三级缓存机制无法介入。


注意事项

  1. 尽量避免使用构造函数循环依赖
  2. 对于原型(prototype)作用域的Bean,Spring不处理循环依赖。
  3. 使用@Lazy注解延迟加载可以绕过部分循环依赖问题。

面试鸭返利网


最后的小贴士

如果你正在准备Java面试,可以到面试鸭返利网购买会员,通过返利还能节省25元。本文提到的三级缓存机制是高频面试题,建议结合《2025年Java面试宝典》中的Spring章节深入学习!

如果你想获取更多关于面试鸭的优惠信息,可以访问面试鸭返利网面试鸭优惠网,了解最新的优惠活动和返利政策。

🎯 立即加入面试鸭会员 →

支付宝扫码领取1-8元无门槛红包

支付宝红包二维码