一、概述
循环依赖是指,多个bean之间相互依赖,形成了一个闭环。比如A依赖于B、B依赖于C、C依赖于A,形成了一个圈。

二、两种方式对循环依赖的影响
2.1、官网说明
2.2、结论
我们AB循环依赖问题只要A的注入方式是setter、并且是singleton,就不会出现循环依赖问题。
三、BeanCurrentlyInCreationException
3.1、构造方法注入
3.1.1、ServiceA
/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/10/27 23:27
 * @Description:
 */
public class ServiceA {
    private ServiceB serviceB;
    public ServiceA(ServiceB serviceB) {
        this.serviceB = serviceB;
        System.out.println("构造方法:A中设置了属性B");
    }
}3.1.2、ServiceB
/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/10/27 23:27
 * @Description:
 */
public class ServiceB {
    private ServiceA serviceA;
    public ServiceB(ServiceA serviceA) {
        this.serviceA = serviceA;
        System.out.println("构造方法:B中设置了属性A");
    }
}3.1.3、xml配置
<!-- 使用构造方法注入属性:会产生循环依赖问题 -->
<bean id="a" class="org.star.component.inject.constructor.ServiceA">
	<constructor-arg name="serviceB" ref="b"/>
</bean>
<bean id="b" class="org.star.component.inject.constructor.ServiceB">
	<constructor-arg name="serviceA" ref="a"/>
</bean>3.1.4、测试
/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/10/27 23:23
 * @Description:
 */
public class SpringCircularDependencyMainApp {
    public static void main(String[] args) {
        m1();
    }
    /**
     * 使用构造方法注入属性:会产生循环依赖问题
     */
    private static void m1() {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        ServiceA serviceA = context.getBean(ServiceA.class);
        System.out.println(serviceA);
    }
}
3.1.5、结论
使用构造方法注入属性:会产生循环依赖问题。
3.2、set方法注入
3.2.1、ServiceAA
/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/10/27 23:30
 * @Description:
 */
public class ServiceAA {
    private ServiceBB serviceBB;
    public ServiceBB getServiceBB() {
        return serviceBB;
    }
    public void setServiceBB(ServiceBB serviceBB) {
        this.serviceBB = serviceBB;
        System.out.println("aa里面设置了属性bb");
    }
}3.2.2、ServiceBB
/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/10/27 23:30
 * @Description:
 */
public class ServiceBB {
    private ServiceAA serviceAA;
    public ServiceAA getServiceAA() {
        return serviceAA;
    }
    public void setServiceAA(ServiceAA serviceAA) {
        this.serviceAA = serviceAA;
        System.out.println("bb里面设置了属性aa");
    }
}3.2.3、xml配置
<!-- 使用set方法注入属性:不会产生循环依赖问题 -->
<bean id="aa" class="org.star.component.inject.setter.ServiceAA">
	<property name="serviceBB" ref="bb"/>
</bean>
<bean id="bb" class="org.star.component.inject.setter.ServiceBB">
	<property name="serviceAA" ref="aa"/>
</bean>3.2.4、测试
/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/10/27 23:23
 * @Description:
 */
public class SpringCircularDependencyMainApp {
    public static void main(String[] args) {
        m2();
    }
    /**
     * 使用set方法注入属性:不会产生循环依赖问题
     */
    private static void m2() {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        ServiceAA aa = context.getBean(ServiceAA.class);
        ServiceBB bb = context.getBean(ServiceBB.class);
        System.out.println(aa);
        System.out.println(bb);
    }
}
3.2.5、结论
使用set方法注入属性:不会产生循环依赖问题
3.3、注意事项
默认的单例bean是支持循环依赖的,但是当把scope的值改为prototype时,将会报错。









