前置文章:
doCreateBean之创建无属性的bean
doCreateBean之处理@Autowired以及@Value标签
doCreateBean完整源码如下:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
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<String> 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.");
}
}
}
}
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
接上文分析到的位置,接下来执行:
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
之后会来到
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
进入到addSingletonFactory:
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
消除此Bean在二级缓存里的缓存信息,将其包装成singletonFactory实例往三级缓存里添加
这里有一个重点就是Spring解决循环依赖的真相就在这一段源码中:在这里beanFactory被put进了singletonFactories ,此时的bean只是完成了初始化构造的bean,还没有进行set或者注解注入的bean,是bean的一个中间状态,但是已经能被人认出来了,所以Spring此时将这个对象提前曝光出来让大家认识、使用。
回到doCreateBean,进入到getEarlyBeanReference
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;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
注意这个方法并不是在doCreateBean的
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
这一行执行的,这里只是将getEarlyBeanReference注册进去,实际执行的地方是前面尝试从缓存里获取bean的地方,即AbstractBeanFactory的doCreateBean方法里。
回到doCreateBean,此时获取到了bean,并且只在三级缓存里面保存。 之后会执行
populateBean(beanName, mbd, instanceWrapper);
来将bean的属性真正注入到里面,然后再调用initializeBean进行彻底的初始化
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
之后判断该bean是否允许提前暴露,
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
......
}
}
if 里面调用了getSingleton方法,进入该方法:
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
和之前提到的是同一个方法,由于这时bean已经被放到三级缓存里了,所以会被从三级缓存里取出
singletonObject = singletonFactory.getObject();
获取到bean实例之后会将其从三级缓存里移除
this.singletonFactories.remove(beanName);
回到doCreateBean,
Object earlySingletonReference = getSingleton(beanName, false);
执行完毕之后再判断一下
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
exposedObject 由于之前调用了initializeBean 方法,所以有可能会被赋值为全新的对象,一旦被赋值了全新的对象之后if里面是false,进入到前面的initializeBean 方法里 重点关注applyBeanPostProcessorsAfterInitialization 方法,进入到方法里: 重点关注实现了postProcessAfterInitialization方法的AbstractAutoProxyCreator类
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
该方法尝试从缓存里获取bean实例并返回,即如果先前加工过的话就返回bean实例,确保加工过的bean实例和先前是同一个。
回到doCreateBean,
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> 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.");
}
}
如果不是同一个bean,则有可能经过initializeBean 之后没有返回同样的bean实例,之所以会出现这个问题是因为postProcessor也是供用户使用的,用户可能在自定义逻辑里修改了bean实例,用户的行为对于系统来说是无法预测的。
不一样的话就会检查有没有别的bean依赖于这个bean,如果存在则直接报错,因为既然执行到这里其他bean实例就已经执行过了populate方法将该bean的实例设置上了,然而设置上了之后却又创建出了该bean的新实例,于是就不满足单例。
通过验证之后会注册销毁时候的回调逻辑
registerDisposableBeanIfNecessary(beanName, bean, mbd);
|