且挨过三冬四夏,暂受些此痛苦。雪尽后再看梅花。
这篇讲解SpringBean实例化过程的关键代码,代码目录可以查找上篇。
首先是getBean->doGetBean
final String beanName = this.transformedBeanName(name);
这里传入的名称可能是别名,做别名解析
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
synchronized(this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject != NULL_OBJECT ? singletonObject : null;
}
走到getSingleton()去缓存池中获取对象,如果singletonObjects和earlySingletonObjects中都没有且singletonFactories里有,会调用getObject()方法获取早期对象,并放入earlySingletonObjects且从singletonFactories中移除包装对象。
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
如果获取到了对象,调用getObjectForBeanInstance处理这里可能是工厂Bean的情况,然后直接返回bean并结束
BeanFactory parentBeanFactory = this.getParentBeanFactory();
if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
String nameToLookup = this.originalBeanName(name);
if (args != null) {
return parentBeanFactory.getBean(nameToLookup, args);
}
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
如果没有获取到对象,则尝试获取父工厂,如果父工厂不为空且当前容易不包含他的bean定义,那么走父工厂的创建流程(回到开始)
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
合并Bean定义,如果存在父Bean是一个抽象Bean
checkMergedBeanDefinition(mbd, beanName, args);
校验当前bean定义不能为抽象
registerDependentBean(dep, beanName);
解析depend-on的bean,如果依赖其他bean需要先创建依赖的bean,这个时候如果A dependon B,B dependon A,会报错
然后根据scope类型来创建Bean,这里只解析单例bean,因为其他类型的都不由spring管理其生命周期
sharedInstance = this.getSingleton(beanName, new ObjectFactory
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
放入singletonsCurrentlyInCreation中表示该对象正在创建
singletonObject = singletonFactory.getObject();
调用getObject()方法即createBean()方法
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
这里是aop的内容,会把切面信息解析并缓存,之后写aop的内容时详解这部分
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
instanceWrapper = createBeanInstance(beanName, mbd, args);
真正创建bean的流程
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
protected void addSingletonFactory(String beanName, ObjectFactory> singletonFactory) {
synchronized(this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
把刚刚创建好的对象 属性还没有赋值的对象通过ObjectFactory的形式加入到缓存中(重要!重要!重要!文章后面会讲下这里怎么解决了循环依赖)
populateBean(beanName, mbd, instanceWrapper);
属性赋值
applyPropertyValues(beanName, mbd, bw, pvs);
获取完所有需要注入的属性后,进行应用
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
转换属性
if (value instanceof RuntimeBeanReference) {
RuntimeBeanReference ref = (RuntimeBeanReference) value;
return resolveReference(argName, ref);
}
如果是运行时Bean,解决引用
bean = this.beanFactory.getBean(refName);
从容器中获取bean(回到开头)
exposedObject = initializeBean(beanName, exposedObject, mbd);
赋值完成后进行对象初始化操作
// 进行Aware接口的回调
invokeAwareMethods(beanName, bean);
// 调用后置处理器的before方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
// 调用初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
// 调用后置处理器的after方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
createBean执行完毕后回到getSingleton方法
afterSingletonCreation(beanName);
把当前的bean从singletonsCurrentlyInCreation中移除掉
addSingleton(beanName, singletonObject);
加入到一级缓存中,并清除二三级缓存中该对象的信息
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
处理工厂bean然后返回对象,整个流程执行结束
所以如果A引用B,B引用A,在创建A的过程中,
在addSingletonFactory将早期对象的包装对象放到缓存中,
在populateBean给属性赋值时解析到了B的引用,走创建B的流程
创建B时进行populateBean时可以获取到A的早期对象,继续进行创建流程
最后将创建好的对象保存在一级缓存中并返回
A获取到B对象继续属性赋值,创建好后保存在一级缓存中并返回