最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Spring循环依赖解析与单例Bean共享机制详解
时间:2026-07-12 09:10:45 编辑:袖梨 来源:一聚教程网
Spring默认采用单例(Singleton)作用域,因此同一类的Bean在IoC容器中仅存在一个共享实例;getBean()多次调用返回的是同一个对象引用,这也是构造器日志仅打印一次的根本原因。
spring默认采用单例(singleton)作用域,因此同一类的bean在ioc容器中仅存在一个共享实例;`getbean()`多次调用返回的是同一个对象引用,这也是构造器日志仅打印一次的根本原因。
在您提供的代码中,DependencyA 和 DependencyB 均未显式声明作用域,因此遵循Spring默认规则:@Component 注解的Bean默认为 singleton 作用域。这意味着:
- 整个Spring容器生命周期内,每个Bean类(如 DependencyA.class)有且仅有一个实例;
- applicationContext.getBean(DependencyA.class) 和 applicationContext.getBean(DependencyB.class) 分别获取各自类型的唯一实例;
- 更关键的是:当 DependencyA 初始化时需注入 DependencyB,Spring会先创建 DependencyB 实例(触发其构造函数),并完成其初始化(包括注入 DependencyA);后续再次调用 getBean(DependencyB.class) 时,直接从一级缓存 singletonObjects 中返回已存在的实例——不再重复构造,故 "I am constructor of Dependency B" 仅输出一次。
这正是Spring三级缓存机制发挥作用的典型场景:
| 缓存层级 | 名称 | 存储内容 | 在循环依赖中的角色 |
|---|---|---|---|
| 一级缓存 | singletonObjects | 完全初始化完毕的成品Bean(可用Bean) | 最终对外提供、getBean() 默认返回来源 |
| 二级缓存 | earlySingletonObjects | 提前曝光的半成品Bean(已实例化,未初始化) | 供其他Bean提前引用,避免死锁 |
| 三级缓存 | singletonFactories | ObjectFactory 工厂对象 | 按需生成早期引用,保障字段/Setter注入可打破循环 |
✅ 您的案例属于“单例 + Setter注入”循环依赖,Spring完全支持:
- 先调用 DependencyA 构造器 → 放入三级缓存 → 触发注入 DependencyB;
- 再调用 DependencyB 构造器 → 放入三级缓存 → 注入 DependencyA 时,通过三级缓存获取 DependencyA 的早期引用(ObjectFactory.getObject())→ 完成 DependencyB 初始化 → 升级至一级缓存;
- DependencyA 继续完成自身属性注入 → 升级至一级缓存。
因此,两次 getBean() 调用本质是获取容器中已就绪的单例对象,而非新建实例。
⚠️ 注意事项:
- 若将任一Bean改为 @Scope("prototype"),每次 getBean() 都会触发全新构造(日志重复打印),但此时循环依赖将直接失败(BeanCurrentlyInCreationException),因原型Bean不参与三级缓存管理;
- Spring 6.0+ / Spring Boot 3.x 默认禁用循环依赖检测(spring.main.allow-circular-references=false),需显式配置为 true 才能启用该机制;
- 构造器注入循环依赖永远无法被Spring自动解决,因其要求依赖必须在构造时就位,与“提前暴露”机制冲突。
// ✅ 正确验证原型行为(将导致循环依赖报错)@Component@Scope("prototype") // ← 添加此注解后,启动将失败class DependencyA { /* ... */ }
总结:getBean() 不创建新实例,而是从容器中共享已有单例——这是Spring高效复用资源的核心设计,也是理解循环依赖能否被解决的前提。合理利用作用域、注入方式与缓存机制,才能写出健壮、可维护的Spring应用。
相关文章
- 苍蓝前线格奈森瑙强度如何-苍蓝前线格奈森瑙强度怎样 07-20
- 出发吧麦芬学者风暴之主养成攻略 07-20
- 英雄冒险团全部传家宝获取方法汇总 07-20
- 王者万象棋新手入门指引 王者万象棋零基础快速上手教程 07-20
- 检疫区最后一站金色收集品怎么获得 隐藏收集品获得方法介绍 07-20
- 息风谷战略牡丹如何获得 息风谷战略牡丹招募与获取方法详解 07-20