ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Java面试被问Spring循环依赖,这样答加分

Java面试被问Spring循环依赖,这样答加分 三级缓存不是重点AOP代理才是二级缓存就能解决普通对象的循环依赖A实例化后放入二级缓存B创建时能从二级缓存拿到A的早期引用。那为什么还要第三级因为如果A需要被AOP代理早期引用必须是代理对象而不是原始对象。第三级缓存singletonFactories存放的是ObjectFactory调用getObject()时才生成代理。二级缓存存的是死对象三级缓存存的是活工厂。面试时你能点出“第三级是为了延迟生成代理保证注入的是代理后的Bean”面试官就知道你不是死记硬背。构造器注入的循环依赖Spring束手无策A的构造器需要BB的构造器需要A。两个对象都还没实例化无法提前暴露引用。Spring直接抛BeanCurrentlyInCreationException。这不是Bug是设计边界。解决办法只有两个改用setter注入或者在其中一个参数上加Lazy让Spring注入一个代理真正调用时才初始化。构造器注入的循环依赖是代码设计的问题不是框架能兜底的。面试时你能说清楚“为什么构造器注入不行”比背十遍三级缓存更有价值。prototype作用域的循环依赖直接报错单例Bean会被缓存所以能提前暴露。prototype每次请求都创建新实例Spring不缓存也就无法提前暴露。A创建时需要BB创建时又需要A死循环直接抛异常。作用域决定了缓存策略缓存策略决定了循环依赖能否被解决。面试时提到这一点说明你理解Spring的Bean生命周期而不只是孤立地背三级缓存。Spring Boot 2.6默认禁止循环依赖这是进步从2.6开始Spring Boot默认禁止循环依赖启动直接报错。想开启得设spring.main.allow-circular-referencestrue。这个默认值的改变是在逼开发者反思循环依赖本身就是坏味道应该从设计上消除而不是靠框架兜底。面试时你能说出这个版本变化并解释为什么官方要禁止面试官会觉得你关注生态演进不是只会啃老本。面试加分回答按这个逻辑走先一句话定性循环依赖分三种单例setter注入能解决构造器注入和prototype解决不了。然后展开单例setter的三级缓存机制重点讲第三级为什么存在。接着讲边界条件展示你知识的颗粒度。最后补一句最佳实践用事件驱动、接口分离、Lazy打破循环而不是依赖框架的兜底能力。俗语说扬汤止沸不如釜底抽薪。能从设计上避免循环依赖才是真正的高手。这么答面试官不仅点头还会在本子上写“深度理解”。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进