1. 什么是循环依赖?

循环依赖:类之间互相注入。

  • 代码清单2-4 基于字段注入的循环依赖示例代码
public class ClassA {
    @Autowired    
    private ClassB classB;
}
public class ClassB {
    @Autowired    
    private ClassA classA;
}

2. Spring怎样解决循环依赖问题?

Spring围绕Bean的生命周期,使用三级缓存机制解决单例bean的Setter注入的循环依赖问题。

2.1 Spring怎样从缓存中获取单例bean?

Page|Spring:从三级缓存结构中获取单例Bean

2.2 Spring循环依赖解决方案?

  • 代码清单2-19 Bean实例化过程中和循环依赖有关的代码
//1. 初始化Bean,通过构造函数创建Bean
instanceWrapper = createBeanInstance(beanName, mbd, args);
//针对循环依赖问题暴露单例工厂类
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
//2. 初始化Bean实例,完成Bean实例的完整创建
populateBean(beanName, mbd, instanceWrapper);
Demo|Spring:基于Setter方法注入的循环依赖场景

海盐,公众号:海盐架构笔记Demo|Spring:基于Setter方法注入的循环依赖场景

  • 构造器循环依赖问题

为什么无法解决构造器循环依赖问题?

无法解决构造器循环依赖问题,只能抛出BeanCurrentlyInCreationException异常。

因为构造器注入过程是发生在Bean初始化的第一个步骤createBeanInstance()中,而这个步骤还没有调用addSingletonFactory()方法完成第三级缓存的构建,自然也就无法从该缓存中获取目标对象。

3. 业务代码出现循环依赖的解决方案?

调整类与类之间的协作关系将循环依赖调整为间接依赖

常见解决方案:提取中介者、转移业务逻辑以及引入回调机制等。前提:合理地提取业务接口,并通过Spring的依赖注入完成对类的有效管理。

前置知识点:

Bean的生命周期

Bean的注册过程

Spring:从三级缓存结构中获取单例Bean

公众号:海盐架构笔记Spring:从三级缓存结构中获取单例Bean

参考:

郑天民著.Spring Boot进阶:原理、实战与面试题分析.机械工业出版社有限公司

郝佳著.Spring源码深度解析(第2版).人民邮电出版社

本篇文章来源于微信公众号: 海盐架构笔记



微信扫描下方的二维码阅读本文

此作者没有提供个人介绍
最后更新于 2023-06-20