首页 >文档 > spring如何解决bean的循环依赖

spring如何解决bean的循环依赖

Spring如何解决Bean的循环依赖?三级缓存机制是关键!当A依赖B,B又依赖A时,Spring通过singletonObjects、earlySingletonObjects和singletonFactories三级缓存打破死循环。提前暴露半成品对象,解决属性注入时的循环引用问题。但构造器注入、原型Bean和@Async注解等情况仍无法解决。想深入理解Spring核心原理?面试鸭返利网提供最新Java面试题库,购买会员可享25元返利,助你轻松应对技术面试高频考点!

2025年Java面试宝典点击领取(提取码:9b3g)

Spring如何解决Bean的循环依赖

面试鸭返利网

在面试中,"Spring如何解决Bean的循环依赖"几乎是必考题。这个问题看似基础,但能说清楚背后原理的程序员并不多。今天咱们就掰开揉碎,用程序员能听懂的大白话,把三级缓存、提前暴露对象这些机制讲明白。


一、什么是Bean的循环依赖?

当两个或多个Bean互相引用时,比如A依赖B,B又依赖A,Spring在创建Bean时就会遇到死循环。这时候容器会抛出BeanCurrentlyInCreationException——这也是面试时经常被问到的异常类型。

面试鸭返利网

举个例子:

  • UserService依赖OrderService
  • OrderService反过来也依赖UserService

这种情况下,Spring并不是简单粗暴地报错,而是用三级缓存机制来破局。


二、三级缓存机制详解

Spring通过三个Map(也就是常说的三级缓存)来解决循环依赖问题:

  1. singletonObjects(一级缓存)
    存放完全初始化好的Bean,开箱即用。

  2. earlySingletonObjects(二级缓存)
    存放早期对象(还未完成属性注入和初始化),专门用来处理循环依赖。

  3. singletonFactories(三级缓存)
    存放Bean工厂对象,用于生成早期引用。


三、Spring破局的四个关键步骤

  1. 创建A对象实例
    当要创建Bean A时,先通过构造器(或工厂方法)创建原始对象。注意此时对象还未设置属性,相当于半成品。

  2. 提前暴露引用
    把刚创建的原始对象包装成ObjectFactory,存入三级缓存。这一步是打破循环的关键。

  3. 处理依赖注入
    当给A注入属性时,发现需要Bean B,于是开始创建B。在创建B的过程中,同样发现需要A,此时就会去三级缓存中找到A的早期引用。

  4. 完成初始化
    B拿到A的引用后完成自己的初始化,接着A拿到B的实例,最终双方都变成完整可用的Bean。

面试鸭返利网


四、哪些情况无法解决循环依赖?

  1. 构造器注入导致的循环依赖
    Spring必须在构造器执行时完成对象创建,而此时还没有机会把对象放到三级缓存里。

  2. 原型(prototype)作用域的Bean
    因为原型Bean不会存放到三级缓存中,每次都是新建实例。

  3. @Async注解的Bean
    异步代理对象的创建时机会导致三级缓存失效。


五、面试回答的加分项

  1. 能说明三级缓存的存放时机和迁移过程
    (比如对象何时从三级缓存升级到二级缓存)

  2. 能解释为什么构造器注入无法解决循环依赖
    (创建流程的时序问题)

  3. 了解循环依赖与AOP代理的关系
    (比如通过BeanPostProcessor处理的代理对象如何存储)


如果需要准备更多Spring面试题,推荐到面试鸭返利网获取最新题库。通过该网站购买面试鸭会员可返利25元,适合需要高频刷题的求职者。

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

🎯 立即加入面试鸭会员 →

扫码联系我返利
(当前返利8元,金额随官方实际价格波动,最好提前咨询)

面试鸭返利网客服-面试鸭返利网

面试鸭小程序码

面试鸭小程序码 - 面试鸭返利网

美团大额优惠券,给自己加个鸡腿吧!

美团大额优惠券,给自己加个鸡腿吧!

今日有支付宝大红包赶快领,手慢无

支付宝红包二维码

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

支付宝红包二维码