-
首先需要说明的是Spring默认是允许循环依赖的,当然可以通过DefaultListxxxx.setCircle(false)让容器不允许循环依赖。
-
其次,循环依赖只能通过set来设置,不能通过构造方法。其实说白了就是一个属性注入。
-
就从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方法,里面干了两件事,一是通过后置处理器来推断构造方法,二是对Bean进行实例化