Spring中的循环依赖
-
首先需要说明的是Spring默认是允许循环依赖的,当然可以通过DefaultListxxxx.setCircle(false)让容器不允许循环依赖。
-
其次,循环依赖只能通过set来设置,不能通过构造方法。而且不能是原型模式,必须是单例。其实说白了就是一个属性注入。
-
最后,描述一下Spring中getBean的大致流程:从容器中拿---验证---创建(从容器中再拿一次)
-
就从refresh方法一步一步开扣,refresh中的finishBeanFactoryInitialization(beanFactory)--->beanFactory.preInstantiateSingletons();------>getBean(beanName);---->doGetBean(name, null, null, false);
好了,暂停开扣,补水:Object sharedInstance = getSingleton(beanName);doGetBean中首先会从单例池中先取一遍,第一次取当然为null不用想。
getSingleton代码
Object singletonObject = this.singletonObjects.get(beanName);//这里第一次取的时候为null
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName));//判断当前的Bean是不是正在被创建,这里是第一次来创建,当然也是FALSE
点击查看代码
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
-
需要注意的是,此时也是调用了getSingleton的另一个重载方法,在该方法中首先会对Bean进行标记,beforeSingletonCreation(beanName);这个方法中就会把当前创建的BeanName放到singletonsCurrentlyInCreation这个Map中,这就和之前的一步关联起来了,这里先按下不表。
-
之后就会调用createBean来创建Bean的实例,接连调用doCreateBean--->createBeanInstance方法,里面干了两件事,一是通过后置处理器(第二次调用后置处理器,如果说有多个质疑的才会有,只有一个的情况为NULL)来推断构造方法,二是对Bean进行实例化。
-
在doCreateBean的applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);方法中第三次调用后置处理器, addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));方法中第四次调用后置处理器,判断是否需要AOP。
-
其中在createBean方法中Object bean = resolveBeforeInstantiation(beanName, mbdToUse);第一次调用了后置处理器(AOP位置)
循环引用的开始是populateBean方法中的属性注入。
// 一般为true,进入
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
- 其中getBeanPostProcessors()可以发现有6个bean后置处理器。AutowiredAnnotationbeanPostProcessor是专门用来处理@Autowired注解,Common开头的专门用来处理@Resource注解。,然后兜兜转转又到了GetBean。

浙公网安备 33010602011771号