Spring如何解决循环依赖?
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
Spring框架通过几种机制来解决循环依赖问题,主要针对单例作用域的Bean。循环依赖通常发生在两个或多个Bean相互引用对方作为自己的属性时。以下是Spring解决循环依赖的关键方法:
提前曝光(Early Bean Reference Exposure):
singleton
作用域创建Bean,并且采用懒初始化策略(即在第一次请求Bean时才创建)。对于循环依赖的情况,Spring会在Bean实例化之后、属性注入之前就将创建中的Bean实例注册到一个预先暴露的Bean工厂(BeanFactory
)中。这样,在后续的Bean创建过程中,即使该Bean还未完成初始化,其他需要依赖它的Bean也能获取到这个半成品的引用,从而打破循环依赖。三级缓存:
singletonObjects
:存储完全初始化的单例Bean。earlySingletonObjects
:存储提前曝光的、尚未完成属性注入的单例Bean实例。singletonFactories
:存储用于创建早期Bean实例的工厂对象,这是比earlySingletonObjects
更早的一个阶段。singletonObjects
查找Bean,如果没有找到,则尝试从earlySingletonObjects
获取,如果还不存在,则从singletonFactories
中创建一个Bean实例并放入earlySingletonObjects
中,以此来解决循环依赖。非延迟初始化和@PostConstruct
/InitializingBean
方法:
@PostConstruct
注解或实现InitializingBean
接口的afterPropertiesSet
方法进行的初始化逻辑。因为这些初始化逻辑是在所有依赖注入完成后执行的,此时若存在循环依赖,会导致无法正常完成初始化。构造器注入与循环依赖:
综上所述,Spring主要是通过提前曝光Bean的未完成实例以及三级缓存机制来解决循环依赖问题,但这一机制不适用于构造器注入导致的循环依赖场景。