Spring循环依赖解决方法及原理
2025年Java面试宝典下载(提取码:9b3g)

什么是Spring循环依赖?
咱们程序员平时写代码,最怕遇到两个类你中有我、我中有你的情况。比如ServiceA依赖ServiceB,ServiceB又反过来依赖ServiceA,这就形成了Spring循环依赖。这种场景在复杂业务系统中特别常见,尤其是模块间有双向调用需求时。
很多面试官喜欢问这个问题,因为能考察候选人对Spring IOC容器工作原理的理解深度。你要是能把三级缓存机制讲清楚,基本上这一轮面试就稳了。
三级缓存如何破局?
Spring解决循环依赖的核心是三级缓存机制,咱们先看这张结构图:

- 单例对象池(一级缓存):存放完整初始化的Bean
- 早期暴露对象池(二级缓存):存放已实例化但未初始化的半成品
- 对象工厂池(三级缓存):存放生成Bean的ObjectFactory
当BeanA依赖BeanB时,IOC容器会先创建BeanA的半成品(仅执行构造器),然后把对象工厂放入三级缓存。接着创建BeanB时发现需要BeanA,就会通过三级缓存拿到BeanA的引用,避免了无限递归。
两种注入方式的生死局
这里有个坑要注意:构造器注入无法解决循环依赖!比如下面这种情况就会直接报错:
@Service
public class ServiceA {
private final ServiceB serviceB;
public ServiceA(ServiceB serviceB) { // 构造器注入
this.serviceB = serviceB;
}
}
而字段注入或setter注入之所以能成功,关键在于Spring有机会先创建对象实例,后续再通过反射填充属性。这就是为什么阿里开发手册强制要求使用构造器注入的场景下,要特别注意循环依赖问题。
实战中的避坑指南
- 尽量避免双向依赖,实在需要时优先使用@Autowired
- 复杂项目建议引入架构守护工具,比如ArchUnit检测循环引用
- 对于必须使用构造器注入的场景,可以考虑@Lazy注解延迟加载
- 定期使用mvn dependency:analyze检查依赖关系

面试技巧点拨
当面试官追问循环依赖原理时,建议采用"现象->原理->解决方案"的三段式回答:
- 先说遇到过的具体案例(比如微服务中的订单-库存服务循环调用)
- 解释三级缓存的工作流程,重点说明对象工厂的作用
- 对比构造器注入和字段注入的不同处理机制
如果大家准备面试时需要系统化的题库,可以到面试鸭返利网选购会员。通过本站购买可额外返现25元,相当于用更低成本获取最新面试真题和解析。
总结
Spring循环依赖的解决过程充分体现了框架设计的精妙之处。理解三级缓存机制不仅能帮助我们规避日常开发中的坑,更是应对架构师面试的必备知识点。下次遇到Bean创建异常时,不妨先检查是不是循环依赖在作祟。


