开发者社区 问答 正文

Spring如何解决循环依赖?

Spring如何解决循环依赖?

展开
收起
1623223622751365 2021-10-26 12:00:48 608 分享 版权
阿里云 AI 助理回答

Spring框架通过几种机制来解决循环依赖问题,主要针对单例作用域的Bean。循环依赖通常发生在两个或多个Bean相互引用对方作为自己的属性时。以下是Spring解决循环依赖的关键方法:

  1. 提前曝光(Early Bean Reference Exposure)

    • 在默认情况下,Spring使用singleton作用域创建Bean,并且采用懒初始化策略(即在第一次请求Bean时才创建)。对于循环依赖的情况,Spring会在Bean实例化之后、属性注入之前就将创建中的Bean实例注册到一个预先暴露的Bean工厂(BeanFactory)中。这样,在后续的Bean创建过程中,即使该Bean还未完成初始化,其他需要依赖它的Bean也能获取到这个半成品的引用,从而打破循环依赖。
  2. 三级缓存

    • Spring使用了三个级别的缓存来管理Bean的创建过程,分别是:
      • singletonObjects:存储完全初始化的单例Bean。
      • earlySingletonObjects:存储提前曝光的、尚未完成属性注入的单例Bean实例。
      • singletonFactories:存储用于创建早期Bean实例的工厂对象,这是比earlySingletonObjects更早的一个阶段。
    • 当Spring遇到循环依赖时,它会先从singletonObjects查找Bean,如果没有找到,则尝试从earlySingletonObjects获取,如果还不存在,则从singletonFactories中创建一个Bean实例并放入earlySingletonObjects中,以此来解决循环依赖。
  3. 非延迟初始化和@PostConstruct/InitializingBean方法

    • 请注意,Spring的循环依赖解决方案仅适用于字段注入(setter注入或构造器注入),不包括通过@PostConstruct注解或实现InitializingBean接口的afterPropertiesSet方法进行的初始化逻辑。因为这些初始化逻辑是在所有依赖注入完成后执行的,此时若存在循环依赖,会导致无法正常完成初始化。
  4. 构造器注入与循环依赖

    • 如果Bean之间是通过构造器注入形成循环依赖,那么Spring无法解决这种类型的循环依赖,因为构造器注入要求在Bean实例化时就必须满足所有的依赖关系。

综上所述,Spring主要是通过提前曝光Bean的未完成实例以及三级缓存机制来解决循环依赖问题,但这一机制不适用于构造器注入导致的循环依赖场景。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答