Spring 循环依赖(两个 bean 之间) - 基于构造器

2025/05/14

一、背景

基于构造器的循环依赖。

二、流程图

三、测试程序

package com.ongoing.demo.circular_dependency.constructor;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class ApplicationDemo {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext =
                new AnnotationConfigApplicationContext("com.ongoing.demo.circular_dependency.constructor");
    }
}
package com.ongoing.demo.circular_dependency.construct;
import org.springframework.stereotype.Component;

@Component
public class Cat {
    public Cat(Person person) {
    }
}
package com.ongoing.demo.circular_dependency.construct;
import org.springframework.stereotype.Component;

@Component
public class Person {
    public Person(Cat cat) {
    }
}

应用运行结果

四、原因

先来看下org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean的主要流程

// 1、创建新实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
// 2、添加单例工厂到第三级缓存
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
// 3、属性赋值、依赖注入。完成 bean 的完整创建
populateBean(beanName, mbd, instanceWrapper);

由于构造器注入是在第一步发生的。 这里:

  1. 先初始化 cat
  2. 发现 cat 的依赖 person,去初始化 person
  3. 发现 person 的依赖 cat,实际通过构造函数再次创建,此时在集合singletonsCurrentlyInCreation发现 cat 正在创建中,被拦截下来报错。

这里 cat 和 person 都不会接触到第三级缓存单例工厂。