属性注入时,spring如何解决循环依赖?

发布时间:2023-08-31 13:00

提前声明:本文是基于spring.5.0.7.RELEASE

测试用例如下:

@Service("transactionServiceTest")
public class TransactionServiceTest implements TransactionService {

    @Autowired
    private UserManager2 userManager2;
}

@Component
public class UserManager2 {

    @Autowired
    private TransactionServiceTest transactionServiceTest;
}

属性注入时,spring如何解决循环依赖?_第1张图片图1
属性注入时,spring如何解决循环依赖?_第2张图片图2
属性注入时,spring如何解决循环依赖?_第3张图片图3

上面的图1、图2、图3分别表示项目启动后我们的测试类的创建顺序:
1.先创建TransactionServiceTest;
2.因为TransactionServiceTest依赖UserManager2,所以紧接着去创建UserManager2;

属性注入时,spring如何解决循环依赖?_第4张图片图4

图4的红色方框的栈线程信息,反映的是spring注入TransactionServiceTest类里面的UserManager2属性;

属性注入时,spring如何解决循环依赖?_第5张图片图5

图5反映的是spring创建UserManager2过程中发现其需要依赖TransactionServiceTest,而注入TransactionServiceTest属性的过程;最终调用了
DefaultSingletonBeanRegistry.getSingleton(beanName);

    public Object getSingleton(String beanName) {
        //注意这里的allowEarlyReference 值 是ture
        return getSingleton(beanName, true);
    }

下面是getSingleton()具体逻辑:

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        //因为此时TransactionServiceTest并没有完成初始化,因此 singletonObject = null;
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            synchronized (this.singletonObjects) {
                singletonObject = this.earlySingletonObjects.get(beanName);
                if (singletonObject == null && allowEarlyReference) {
                    //最终在获取TransactionServiceTest对应的lamda表达式
                    ObjectFactory singletonFactory = this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        //这里执行lamda表达式,获取singletonObject实例
                        singletonObject = singletonFactory.getObject();
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        //lambda表达式删掉
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        //最终返回singletonObject实例
        return singletonObject;
    }

lambda表达式的逻辑如下:

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
        Object exposedObject = bean;
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                    SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                    //调用AutowiredAnnotationBeanPostProcessor.getEarlyBeanReference方法;
                    //如果此时有必要被代理,也会在这里调用相应的后置处理器生成代理对象
                    exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
                }
            }
        }
        return exposedObject;
    }

lambda表达式执行完成之后,生成一个早期对象,为什么叫早期对象呢?因为此时的bean对象还没有被执行初始化逻辑;

接下来,UserManager2执行初始化逻辑,初始化完成后,TransactionServiceTest接着进行初始化。至此,循环依赖处理完成。

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号