【Spring】三级缓存与循环依赖:面试高频考点全解析

📅 发布时间:2026/7/9 0:00:07 👁️ 浏览次数:
【Spring】三级缓存与循环依赖:面试高频考点全解析
前言本篇针对Spring 三级缓存与循环依赖将其面试题高频考点全解析。一、什么是循环依赖答循环依赖指两个或多个 Bean 之间相互依赖形成闭环。例如双向依赖A 的属性需要注入 BB 的属性需要注入 A!-- 一种双向循环情况--beanclasscom.pojo.EraserideraserautowirebyNameconstructor-argrefpencil//beanbeanclasscom.pojo.PencilidpencilautowirebyNameconstructor-argreferaser//bean二、Spring 如何解决循环依赖答需要满足两个条件1.必须是单例原因是只有单例才能存入到三级缓存中2.必须是setter注入。核心是依赖三级缓存这三级缓存定义在DefaultSingletonBeanRegistry中本质是三个 Map。缓存名称作用一级缓存存储完全初始化完成的单例 Bean可直接使用二级缓存存储未完全初始化但已提前暴露的单例 Bean 早期引用三级缓存存储生成 Bean 早期引用的工厂对象接下来必讲三级缓存解决循环依赖的完整流程三、三级缓存解决循环依赖的完整流程答以双向依赖为例以下是完整流程。1.实例化A调用 A 的无参构造。2.暴露A 的工厂为A创建工厂对象并将该工厂存入三级缓存。3.注入 A 的属性调用A的setB方法找一-二-三级缓存但是没有找到b的实例于是…4.实例化B调用B的无参构造5.暴露B的工厂为B创建工厂对象并将该工厂存入三级缓存。6.注入B的属性调用B的setA方法找一-二-三级缓存找到了A的工厂对象于是成 A 的早期引用为了避免重复生再将A 的早期引用迁移到二级缓存而B形成完整的bean放入一级缓存7.现在回到了A的属性注入找一级缓存直接找到了B的实例注入成功A形成完整的bean放入一级缓存四、为什么需要三级缓存两级不够吗答支持 AOP 代理场景下的循环依赖。若只有两级缓存Bean 实例化后需直接暴露早期引用到二级缓存。但如果 Bean 需要 AOP 代理暴露的会是原始对象而最终需要的是代理对象导致注入的对象与最终 Bean 不一致。其价值是只有当发生循环依赖时才会调用工厂生成代理对象或原始对象确保注入的是最终需要的实例代理或原始同时避免提前生成代理破坏 Bean 的生命周期代理逻辑应在初始化后执行。总结1.循环依赖是 Bean 间相互依赖形成的闭环会导致初始化失败。2.Spring 通过三级缓存解决单例 Bean 的字段注入循环依赖三级缓存分别存储成品 Bean、早期引用、生成早期引用的工厂。3.核心流程是 “实例化→暴露工厂→查找依赖→提前引用→完成初始化”。4.三级缓存的关键是支持 AOP 代理场景避免注入对象与最终 Bean 不一致。如有疑问或漏洞欢迎指出感谢浏览~