目录
2.2 创建Bean:doCreateBean的createBeanInstance方法
2.2.1 通过Supplier实例化 —— obtainFromSupplier
2.2.2 通过factory-method实例化 —— instantiateUsingFactoryMethod
2.2.3 自动绑定构造函数 —— autowireConstructor
2.2.4 普通Bean的实例化 —— instantiateBean
2.3 Bean创建后的后处理:doCreateBean的剩余部分
当ApplicationContext完成refresh之后,容器就已经读取并解析了所有的Bean定义,安装了设定的扩展,并且对需要提前实例化的Bean创建了单例。这之后就可以获取XML中配置的Bean了,获取Bean的方法是容器的getBean()方法,实际调用了AbstractBeanFactory的doGetBean方法。
1.获取Bean单例实例
在容器扩展结束后,实际上已经对非懒加载、scope为“singleton”的Bean进行过实例化了,如果此时需要获取的Bean已经实例化,那么直接返回就可以,不需要重新实例化。
String beanName = this.transformedBeanName(name);
Object sharedInstance = this.getSingleton(beanName);
Object bean;
if (sharedInstance != null && args == null) {
if (this.logger.isTraceEnabled()) {
if (this.isSingletonCurrentlyInCreation(beanName)) {
this.logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
} else {
this.logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
}
transformedBeanName是将传入的名称通过在aliasMap中查找的方式,转换为BeanName。
getSingleton就是根据BeanName,尝试从存储Bean单例实例的Map中取出实例对象,假如单例对象不存在,或者正在创建,那么就尝试获取单例工厂,并产生单例对象:
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;
}
earlySingletonObjects和singletonObjects的不同之处在于,前者包含了还处在创建过程中的单例对象,主要是用来防止循环依赖。只有当两个单例列表中都没有要找到Bean时,才会尝试创建一个。
紧接着,容器尝试从Bean实例中获取对象,之所以是获取对象而不是直接返回实例,从源码中就能看出原因:
protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(this.transformedBeanName(name), beanInstance.getClass());
}
}
if (beanInstance instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
Object object = null;
if (mbd == null) {
object = this.getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
FactoryBean<?> factory = (FactoryBean)beanInstance;
if (mbd == null && this.containsBeanDefinition(beanName)) {
mbd = this.getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = mbd != null && mbd.isSynthetic();
object = this.getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
} else {
return beanInstance;
}
}
原因就在于,Bean有两种,普通的Bean当然可以直接返回实例,但是对于FactoryBean,它是用来产生其他对象的,直接返回实例一般而言没有什么用,所以在这里需要进行判断。isFactoryDereference方法用来检测Bean名称是否以"&"开头,假如一个Bean不是FactoryBean却又以"&"开头,那么就是配置有问题,当然不能进行实例化。假如一个Bean是FactoryBean,且不以"&"开头,则说明用户想要它产生一个对象,则先尝试从缓存获取FactoryBean,否则用传入的Bean创建实例。由于传入的mbd是空,所以会触发getMergedLocalBeanDefinition方法,将本容器中名称为beanName的GenericBeanDefinition转换为RootBeanDefinition,假如要转换的是个子元素,则与父元素的相关属性进行合并。isSynthetic方法用于判断RootBeanDefinition是不是用户定义的。
getObjectForBeanInstance进行了一些判断,然后将核心逻辑交给了getObjectFromFactoryBean处理,它首先判断了传入的Bean是否是单例模式以及单例列表中是否有该Bean,如果答案全部都是true,则需要验证是不是已经创建过实例了,是则直接返回,否则尝试创建实例。实例创建成功后,还会根据是否需要后处理,执行相应方法:
synchronized(this.getSingletonMutex()) {
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
object = this.doGetObjectFromFactoryBean(factory, beanName);
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
} else {
if (shouldPostProcess) {
if (this.isSingletonCurrentlyInCreation(beanName)) {
return object;
}
this.beforeSingletonCreation(beanName);
try {
object = this.postProcessObjectFromFactoryBean(object, beanName);
} catch (Throwable var14) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's singleton object failed", var14);
} finally {
this.afterSingletonCreation(beanName);
}
}
if (this.containsSingleton(beanName)) {
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
假如判断有false,那么就简单了,由于没有限定Bean必须是单例,直接尝试让Factory产生对象即可。可以看到,这个方法又是进行了一些判断和后处理,核心逻辑又被委托给了doGetObjectFromFactoryBean,这次在代码中调用了factory.getObject()来产生对象。
2.完整创建Bean
2.1 Bean创建的前置处理
假如上一步获取单例实例时,单例列表中还没有需要的Bean的实例,说明待获取的Bean,要么其scope是prototype,要么它设置了lazy-init为true,即需要在使用时创建。代码首先判断了Bean是否正在创建,如果没有,则会检查当前BeanFactory是否包含需要创建的Bean定义,不包含则委托给父工厂创建,包含则自己创建。然后就会获取待创建Bean的RootBeanDefinition,并处理依赖关系:
RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
this.checkMergedBeanDefinition(mbd, beanName, args);
String[] dependsOn = mbd.getDependsOn();
String[] var11;
if (dependsOn != null) {
var11 = dependsOn;
int var12 = dependsOn.length;
for(int var13 = 0; var13 < var12; ++var13) {
String dep = var11[var13];
if (this.isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
this.registerDependentBean(dep, beanName);
try {
this.getBean(dep);
} catch (NoSuchBeanDefinitionException var24) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var24);
}
}
}
getMergedLocalBeanDefinition上面有提到,作用是让子Bean元素继承父元素的属性;checkMergedBeanDefinition的作用是检查Bean是否是抽象的;dependsOn指的是由depends-on属性配置依赖的Bean,这些被依赖的Bean肯定是优先进行实例化的。处理依赖Bean时,首先检查了是否存在循环依赖,然后对Bean及其依赖注册依赖关系,最后尝试获取被依赖的Bean(如果被依赖的Bean还没初始化,会在这一步进行),假如该Bean不存在,则抛出异常。
接下来,开始根据Bean的不同scope采用不同的实例化方式,首先是单例Bean:
if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
核心方法就是createBean和getObjectForBeanInstance,后者已经见过了,主要看下前者,把日志、try-catch块都去掉,核心代码如下:
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
mbdToUse.prepareMethodOverrides();
Object beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
if (beanInstance != null) {
return beanInstance;
}
return this.doCreateBean(beanName, mbdToUse, args);
}
首先将beanName解析为Class对象,如有必要则赋给RootBeanDefinition对象,然后在prepareMethodOverrides方法中处理lookup-method和replace-method属性,在该方法中,检查了Bean类定义中,指定的覆盖方法的个数,并标记MethodOverride的overloaded属性,假如该属性为true,则实例化的时候会为这个Bean动态生成代理并进行增强处理。之后的resolveBeforeInstantiation就是在实例化前做些前置处理,实际调用了两个方法:applyBeanPostProcessorsBeforeInstantiation、applyBeanPostProcessorsAfterInitialization,前者是在AbstractBeanDefinition转换为BeanWrapper前最后一次可以修改BeanDefinition的机会,会调用PostProcessor对Bean进行处理:
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeIns