当存在循环依赖时,主bean对象(spring先加载的bean是主bean)不能通过构造函数的方式注入所依赖的bean对象,而所依赖的bean对象则不受限制,即可以通过三种注入方式的任意一种注入主bean对象。如果主bean对象通过构造函数方式注入所依赖的bean对象,则无论所依赖的bean对象通过何种方式注入主bean,都无法解决循环依赖问题,程序无法启动。
    原因主要是如果主bean对象通过构造函数注入所依赖bean对象时,无法创建该所依赖的bean对象,获取该所依赖bean对象的引用。因为如下代码所示,假如在创建主bean对象:
    1. createBeanInstance是调用构造函数创建主bean对象,在里面会注入构造函数中所依赖的bean,而此时并没有执行到addSingletonFactory方法来添加主bean对象的创建工厂到三级缓存singletonFactories中。
    2. 故在createBeanInstance内部,注入和创建该主bean对象在构造函数中所依赖的其他bean对象时,假如主bean对象为A,存在对主bean对象依赖的其他bean对象为B,则B无法通过三级缓存机制获取主bean对象A的引用(即B如果通过构造函数注入A,则无法创建B对象;如果通过属性注入或者setter方法注入A,则创建B对象后,对B对象进行属性赋值,会卡在populateBean方法也无法返回),故无法创建主bean对象所依赖的B,创建主bean对象A时,createBeanInstance方法无法返回,出现代码死锁,程序报循环依赖错误。

    1. // bean对象实例创建的核心实现方法
    2. protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
    3. throws BeanCreationException {
    4. // 省略其他代码
    5. // 1. 调用构造函数创建该bean对象,若不存在构造函数注入,顺利通过
    6. instanceWrapper = createBeanInstance(beanName, mbd, args);
    7. // 2. 在singletonFactories缓存中,放入该bean对象,以便解决循环依赖问题
    8. addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    9. // 3. populateBean方法:bean对象的属性赋值
    10. populateBean(beanName, mbd, instanceWrapper);
    11. // 省略其他代码
    12. return exposedObject;
    13. }