2025年最新Java面试资料已更新!包含Spring循环依赖等高频考点:
🔗 点击领取《2025年Java面试宝典》
提取码:9b3g(建议保存到网盘,避免失效)

一、什么是Spring循环依赖?
用大白话说就是两个Bean互相需要对方:A创建时发现依赖B,B创建时又发现依赖A。比如用户服务依赖订单服务,而订单服务也需要查询用户信息,这时候就形成了"你等我创建,我等你初始化"的死锁场景。
很多面试官会追问:"你项目中遇到过循环依赖吗?怎么解决的?"这时候如果直接说"用@Lazy注解",可能只会拿到及格分。我们要从设计层面说清底层原理才能拿到高分。
二、三级缓存破局之道
Spring通过三级缓存机制打破循环依赖,这个设计非常巧妙:
- 一级缓存(singletonObjects):存放完整初始化后的Bean
- 二级缓存(earlySingletonObjects):存放提前暴露的原始对象
- 三级缓存(singletonFactories):存放Bean工厂对象

当A开始创建时:
- 实例化后立刻将对象工厂放入三级缓存
- 填充属性时发现需要B
- 开始创建B,B同样在填充属性时发现需要A
- 此时从三级缓存拿到A的早期引用,完成B的创建
- 最后A拿到完整的B对象,完成自身初始化
三、构造函数循环依赖无解?
这里有个重要例外:构造函数注入导致的循环依赖无法解决。因为此时对象还没创建完成,连早期引用都无法生成。这也是为什么Spring官方推荐使用属性注入而不是构造器注入的原因之一。
有同学可能会问:"那为什么@Lazy注解能解决问题?"其实它只是延迟了依赖加载的时间,并没有真正打破循环链。在面试中能说出这个区别,会让面试官觉得你理解很透彻。
四、实战避坑指南
实际开发中要注意:
- 避免非必要的事务注解(AOP代理会改变Bean类型)
- 复杂项目中使用@DependsOn明确依赖顺序
- 优先使用Setter注入而不是构造器注入

如果大家在准备面试时需要系统复习Spring原理,推荐通过面试鸭返利网购买官方会员,用我的邀请码可以返现25元。最新面经题库和Spring源码解析都已经更新到2025版,覆盖大厂高频考点。
最后再提醒下,理解循环依赖解决方案不仅要会说三级缓存,更要能说清楚为什么这么设计、不同注入方式的区别、以及如何预防这类问题。这才是高级开发者应该具备的系统性思维。


