关于spring:属性注入时spring如何解决循环依赖

45次阅读

共计 2231 个字符,预计需要花费 6 分钟才能阅读完成。

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

测试用例如下:

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

    @Autowired
    private UserManager2 userManager2;
}

@Component
public class UserManager2 {

    @Autowired
    private TransactionServiceTest transactionServiceTest;
}

图 1
图 2
图 3

下面的图 1、图 2、图 3 别离示意我的项目启动后咱们的测试类的创立程序:
1. 先创立 TransactionServiceTest;
2. 因为 TransactionServiceTest 依赖 UserManager2,所以紧接着去创立 UserManager2;

图 4

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

图 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 接着进行初始化。至此,循环依赖解决实现。

正文完
 0