Spring默认采用单例(Singleton)作用域,因此同一类的Bean在整个IoC容器中仅存在一个共享实例;getBean()多次调用返回的是同一个对象引用,而非新实例——这正是循环依赖能被解决且构造器只执行一次的根本原因。
spring默认采用单例(singleton)作用域,因此同一类的bean在整个ioc容器中仅存在一个共享实例;`getbean()`多次调用返回的是同一个对象引用,而非新实例——这正是循环依赖能被解决且构造器只执行一次的根本原因。
在你提供的代码中,DependencyA 和 DependencyB 均未显式声明作用域,因此遵循Spring默认规则:@Scope("singleton")。这意味着:
DependencyA dependencyA = applicationContext.getBean(DependencyA.class); // 返回已创建好的ADependencyB dependencyB = applicationContext.getBean(DependencyB.class); // 返回已创建好的B
——两者均从 singletonObjects 直接获取,不再触发构造函数,故 "I am constructor of Dependency B" 仅输出一次。
若希望每次 getBean() 都新建实例(即构造器重复执行),需显式指定作用域:
@Component@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) // 或 @Scope("prototype")class DependencyB { // ... 同上}
此时运行将抛出 BeanCurrentlyInCreationException:因为Prototype Bean不参与三级缓存机制,Spring无法提前暴露其引用,循环依赖将直接失败——这也印证了单例+字段/Setter注入是Spring唯一支持循环依赖的组合。
System.out.println(System.identityHashCode(dependencyA)); // 例如:123456789System.out.println(System.identityHashCode(applicationContext.getBean(DependencyA.class))); // 相同值
总结:getBean() 不“创建”Bean,而是“获取”容器中已管理的实例;单例作用域下的循环依赖之所以可行,本质是Spring利用三级缓存实现了对象实例化与初始化的时空解耦——先有“壳”,再填“瓤”,从而在闭环中建立可靠引用链。
Ruby实现二分搜索(二分查找)算法的简单示例
Muse Spark 1.2 Contributor 模型说明:价格、数据约定与用途
Muse Spark 2026 版本时间线与规格:1.1 至 1.3 能力梳理
Muse AI 官网入口与登录方法:账号设置及常见问题
Muse Spark 1.2 实测表现:基准数据、编程能力与版本选择
Muse Spark 1.1 API 费用解析:输入、输出与缓存计费