addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, “Initialization of bean failed”, ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
“Bean with name '” + beanName + “’ has been injected into other beans [” +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
“‘getBeanNamesOfType’ with the ‘allowEagerInit’ flag turned off, for example.”);
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, “Invalid destruction signature”, ex);
}
return exposedObject;
}

对应的文章《SpringloC容器的依赖注入源码解析(7)—— doCreateBean之剩余逻辑(解决循环依赖的源头)》

现在有A依赖B,B也依赖A,假设A先创建,就会来到doCreateBean方法里,会经过各种包装,在被

instanceWrapper = createBeanInstance(beanName, mbd, args);

处理了之后生成一个没有任何属性的A的实例。

之后在调用

addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

非spring管理的类取值bean_sed

之前将A实例放入到ObjectFactory里面,然后调用addSingletonFactory将ObjectFactory添加到三级缓存里,此时只有三级缓存保存了A对应的ObjectFactory实例。

随后就会调用

populateBean(beanName, mbd, instanceWrapper);

给属性赋值,由于A依赖于B,在populate里会尝试获取实例B,由于B还没有被创建过,所以又递归的调用doCreateBean方法。

doCreateBean方法里调用

instanceWrapper = createBeanInstance(beanName, mbd, args);

创建出实例B,将其对应的实例工厂放入到三级缓存中,此时三级缓存中就保存了A和B的实例,随后在B里又会执行

populateBean(beanName, mbd, instanceWrapper);

由于B依赖A,所以在populate里尝试获取A的实例,此时调用的是AbstractBeanFactory的doGetBean方法,在里面调用:

Object sharedInstance = getSingleton(beanName);

从三级缓存里获取A实例对应的ObjectFactory实例

非spring管理的类取值bean_sed_02

这里getObject()调用的就是getEarlyBeanReference方法

非spring管理的类取值bean_学习_03

获取到A实例之后就会将A实例放入二级缓存里,同时清空三级缓存里的A