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

提前声明:本文是基于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
属性注入时,spring如何解决循环依赖()
文章图片
图2
属性注入时,spring如何解决循环依赖()
文章图片
图3
上面的图1、图2、图3分别表示项目启动后我们的测试类的创建顺序:
1.先创建TransactionServiceTest;
2.因为TransactionServiceTest依赖UserManager2,所以紧接着去创建UserManager2;
属性注入时,spring如何解决循环依赖()
文章图片
图4
图4的红色方框的栈线程信息,反映的是spring注入TransactionServiceTest类里面的UserManager2属性;
属性注入时,spring如何解决循环依赖()
文章图片
图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; }

【属性注入时,spring如何解决循环依赖()】lambda表达式执行完成之后,生成一个早期对象,为什么叫早期对象呢?因为此时的bean对象还没有被执行初始化逻辑;
接下来,UserManager2执行初始化逻辑,初始化完成后,TransactionServiceTest接着进行初始化。至此,循环依赖处理完成。

    推荐阅读