Spring面试题-Spring是怎么解决循环依赖的?

Spring 使用了三级缓存来解决单例模式下的 setter 循环依赖问题。这三级缓存分别是:

一级缓存(singletonObjects):用于存放完全初始化好的单例 Bean。

二级缓存(earlySingletonObjects):用于存放部分初始化完成的单例 Bean,这些 Bean 已经完成了实例化但尚未完成属性填充和初始化。这个缓存主要用于解决循环依赖问题。

三级缓存(singletonFactories):用于存放 Bean 工厂,这些工厂能够在需要时生成 Bean 实例。当 Spring 检测到循环依赖时,它会将尚未初始化的 Bean 的工厂放入三级缓存中,并在需要时通过该工厂创建 Bean 实例。

解决过程

当 Spring 容器创建 Bean A 时,如果发现 Bean A 依赖于 Bean B,并且 Bean B 又依赖于 Bean A,Spring 会按照以下步骤处理循环依赖:

  1. 创建 Bean A:首先,Spring 容器会尝试创建 Bean A 的实例。
  2. 检查缓存:在创建过程中,Spring 会检查一级缓存(singletonObjects)和二级缓存(earlySingletonObjects)中是否已经存在 Bean A 的实例。如果不存在,则继续创建。
  3. 放入三级缓存:在 Bean A 的实例化阶段完成后(即调用了构造器),但属性填充和初始化尚未开始时,Spring 会将 Bean A 的工厂放入三级缓存(singletonFactories)中。
  4. 创建 Bean B :接下来,Spring 容器会创建 Bean B 的实例。在创建过程中,如果 Bean B 依赖于 Bean A,Spring 会从三级缓存中获取 Bean A 的工厂,并调用其 getObject 方法来创建 Bean A 的早期引用(即部分初始化的 Bean A 实例),然后将其注入到 Bean B 中。
  5. 完成 Bean B 的创建:Bean B 完成创建后,会被放入一级缓存(singletonObjects)中。
  6. 完成 Bean A 的创建:最后,Spring 容器会完成 Bean A 的属性填充和初始化,并将其放入一级缓存(singletonObjects)中。此时,Bean A 和 Bean B 都已经完成了完整的初始化过程,并且没有发生循环依赖错误。
相关推荐
时间的拾荒人8 小时前
CMake 实战指南:从基础语法到静态库/动态库制作与链接
开发语言·c++·面试
道尔柯南8 小时前
C++ STL 入门详解:从认识标准模板库到掌握学习方法
java·c++·学习方法
杨凯凡8 小时前
Spring Boot 4 升级为什么卡在 Jackson 3?包名、配置与兼容迁移指南
java·spring boot 4·技术升级·jackson 3·spring framework
天天被压力8 小时前
【A股分钟级高频数据完全手册 #01】Pro版接口体系总览与REST鉴权:42篇地图与从0接入
java·人工智能·python
xyouyuweizhu8 小时前
Java InetAddress 详解:从 IP 地址表示到主机名解析
java·开发语言·python
AI你一生一世17 小时前
不止于时序存储:DolphinDB 如何成为 AI 时代的工业智能底座
java·人工智能·struts·时序数据库·工业智能·dolphindb·ai基础设施
云-缩影17 小时前
拆解 AI 图像生成应用的后端架构:ECS、OSS 和大模型 API 怎么配合
java·spring boot·后端
瑞克-桑切斯17 小时前
7、MySQL 慢查询排查与优化实战指南
java·服务器·数据库
Flynn Liang21 小时前
AI 应用的安全红线:Spring AI 下的 Prompt 注入防护、PII 脱敏、输出审计与密钥管理
人工智能·安全·spring·数据泄露·springai·prompt注入
QCoding21 小时前
企业级Agent Evaluation实战:Agent能跑就能上线?AI Agent到底怎么测?
后端·spring