目录
1.获取Bean单例实例
2.完整创建Bean
2.1 Bean创建的前置处理
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的剩余部分
2.3.1 调用PostProcessor
2.3.2 提前暴露
2.3.3 属性填充
2.2.4 Bean的初始化
2.3.5 继续处理提前暴露
2.3.6 Bean转化为DisposableBean
3.doGetBean的后续操作
当ApplicationContext完成refresh之后,容器就已经读取并解析了所有的Bean定义,安装了设定的扩展,并且对需要提前实例化的Bean创建了单例。这之后就可以获取XML中配置的Bean了,获取Bean的方法是容器的getBean()方法,实际调用了AbstractBeanFactory的doGetBean方法。
在容器扩展结束后,实际上已经对非懒加载、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()来产生对象。
假如上一步获取单例实例时,单例列表中还没有需要的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.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
后者的逻辑和applyBeanPostProcessorsBeforeInstantiation相似,只是变成调用BeanPostProcessor的postProcessAfterInitialization方法。
接下来,就是真正创建Bean的doCreateBean方法。首先是将Bean转化为BeanWrapper,对于单例Bean,需要先从实例缓存中移除已有实例,否则(或者缓存里没有已有实例)创建一个新实例:
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;
}
可以看到,其核心方法是createBeanInstance方法。下面对其进行介绍。
首先处理了两种工厂式Bean,前者直接获取Supplier对象产生实例,后者通过配置的工厂方法产生目标对象:
Supplier> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
首先了解下Supplier,该接口在Spring中的默认实现只有一个,即SingletonSupplier,核心方法为get,实际调用了内部包含的instanceSupplier或defaultSupplier的get方法创建实例。其用途是,可以用factory-method方法或者构造方法构建,构建时会包含一个实例或一到两个Supplier,需要获取实例时,采用double-check的方式返回内部存储的实例,从而保持单例性。
关键方法就三个:Supplier的get方法、BeanWrapperImpl的构造方法、initBeanWrapper方法。get方法上面介绍过了,对于剩下的两个方法。前者直接调用了父类构造方法,代码如下,就是进行一些属性的设置,TypeConverterDelegate顾名思义,是用来进行类型转换的:
protected AbstractNestablePropertyAccessor(Object object) {
registerDefaultEditors();
setWrappedInstance(object);
}
protected void registerDefaultEditors() {
this.defaultEditorsActive = true;
}
public void setWrappedInstance(Object object, @Nullable String nestedPath, @Nullable Object rootObject) {
this.wrappedObject = ObjectUtils.unwrapOptional(object);
Assert.notNull(this.wrappedObject, "Target object must not be null");
this.nestedPath = (nestedPath != null ? nestedPath : "");
this.rootObject = (!this.nestedPath.isEmpty() ? rootObject : this.wrappedObject);
this.nestedPropertyAccessors = null;
this.typeConverterDelegate = new TypeConverterDelegate(this, this.wrappedObject);
}
initBeanWrapper处,为刚刚生成的BeanWrapper对象设置了ConversionService,并使用容器中注册的CustomEditor配置BeanWrapper:
protected void initBeanWrapper(BeanWrapper bw) {
bw.setConversionService(getConversionService());
registerCustomEditors(bw);
}
容器的ConversionService和registerCustomEditors都已经已经很熟悉了,BeanWrapper的呢?看下源码,果然就是把容器的相关属性赋给BeanWrapper
protected void registerCustomEditors(PropertyEditorRegistry registry) {
PropertyEditorRegistrySupport registrySupport = (registry instanceof PropertyEditorRegistrySupport ? (PropertyEditorRegistrySupport) registry : null);
if (registrySupport != null) {
registrySupport.useConfigValueEditors();
}
if (!this.propertyEditorRegistrars.isEmpty()) {
for (PropertyEditorRegistrar registrar : this.propertyEditorRegistrars) {
registrar.registerCustomEditors(registry);
}
}
if (!this.customEditors.isEmpty()) {
this.customEditors.forEach((requiredType, editorClass) ->
registry.registerCustomEditor(requiredType, BeanUtils.instantiateClass(editorClass)));
}
}
此处可以看出,要初始化的并不是FactoryBean的实现类的getObject方法,而是配置了factory-method、factory-bean属性的Bean的方法,因此,其开头部分和obtainFromSupplier一致,但是接下来就有很多额外的检验和处理,首先是对factory-bean的的处理:
//和obtainFromSupplier一致
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
//对Bean进行一定的校验
String factoryBeanName = mbd.getFactoryBeanName();
Object factoryBean;
Class factoryClass;
boolean isStatic;
//如果配置了factory-bean
if (factoryBeanName != null) {
//防止出现回环
if (factoryBeanName.equals(beanName)) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "factory-bean reference points back to the same bean definition");
}
//防止创建重复实例,破坏单例性
factoryBean = this.beanFactory.getBean(factoryBeanName);
if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
throw new ImplicitlyAppearedSingletonException();
}
factoryClass = factoryBean.getClass();
isStatic = false;
} else {
if (!mbd.hasBeanClass()) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "bean definition declares neither a bean class nor a factory-bean reference");
}
factoryBean = null;
factoryClass = mbd.getBeanClass();
isStatic = true;
}
接下来对factory-method进行处理,如果没有可用的factory-method配置,或者没有配置参数,就需要进行方法匹配,由于方法很可能存在重载版本,所以需要先解析配置的参数列表,以确定要调用哪个版本的重载方法:
Method factoryMethodToUse = null;
ConstructorResolver.ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
if (explicitArgs != null) {
argsToUse = explicitArgs;
} else {
Object[] argsToResolve = null;
synchronized(mbd.constructorArgumentLock) {
factoryMethodToUse = (Method)mbd.resolvedConstructorOrFactoryMethod;
if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
if (argsToResolve != null) {
argsToUse = this.resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve, true);
}
}
resolvePreparedArguments根据参数类型,分别采用不同的方法处理,在有必要时,用BeanWrapper的TypeConverter进行参数类型转换:
if (argValue instanceof ConstructorResolver.AutowiredArgumentMarker) {
argValue = this.resolveAutowiredArgument(methodParam, beanName, (Set)null, (TypeConverter)converter, fallback);
} else if (argValue instanceof BeanMetadataElement) {
argValue = valueResolver.resolveValueIfNecessary("constructor argument", argValue);
} else if (argValue instanceof String) {
argValue = this.beanFactory.evaluateBeanDefinitionString((String)argValue, mbd);
}
resolvedArgs[argIndex] = ((TypeConverter)converter).convertIfNecessary(argValue, paramType, methodParam);
然后就可以根据解析出来的参数列表找到匹配的方法重载版本了。匹配方法有以下情形:
在代码中也可以看到,factory-method属性对应的方法返回类型不能为void。
实例化的关键方法是instantiate方法,它调用了容器设置的实例化策略进行实例化,对于DefaultListableBeanFactory,其使用CGLib进行实例化:
private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
CglibSubclassingInstantiationStrategy继承自SimpleInstantiationStrategy,调用BeanUtils.instantiateClass方法进行实例创建,实际上借助了反射机制调用方法。
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,@Nullable Object factoryBean, final Method factoryMethod, Object... args) {
...
Object result = factoryMethod.invoke(factoryBean, args);
...
}
调用该方法有以下情形:
对于第二种情形,源码如下,实际就是遍历并找到SmartInstantiationAwareBeanPostProcessor实例,由它来决定候选的构造函数列表:
protected Constructor>[] determineConstructorsFromBeanPostProcessors(@Nullable Class> beanClass, String beanName) throws BeansException {
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
Constructor>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
return ctors;
}
}
}
}
return null;
}
不过上面提到的SmartInstantiationAwareBeanPostProcessor默认没有配置,即其结果一般是null,所以就要根据auto-wire属性来判断自动装配模式:
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
autowire共有以下几种可选项:
现在可以来看autowireConstructor的内容了。它调用了ConstructorResolver的同名方法,整体逻辑和instantiateUsingFactoryMethod很相似。该方法主要做了以下几件事:
和instantiateUsingFactoryMethod一样,方法开头也创建了BeanWrapper对象并进行初始化。然后根据情况确定将要使用的参数列表。优先使用getBean时传入的参数,否则从缓存读取构造函数对象和参数列表,并根据构造函数需求进行参数转换:
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
constructorToUse = (Constructor>) mbd.resolvedConstructorOrFactoryMethod;
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached constructor...
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
if (argsToResolve != null) {
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
}
}
resolvePreparedArguments调用了容器中注册的TypeConverter进行参数类型转换,假如参数中有其它Bean,即存在依赖关系,则调用了BeanFactory的resolveDependency方法进行处理。该方法会在下面详细介绍。
假如缓存中已经有想要的一切原料,则可以直接进行实例化,否则还需要进一步解析。首先是解析候选的Constructor对象,如果有通过参数传入,就直接使用,否则从Bean的定义中读取:
Constructor>[] candidates = chosenCtors;
if (candidates == null) {
Class> beanClass = mbd.getBeanClass();
candidates = (mbd.isNonPublicAccessAllowed() ?
beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}
假如得到的候选构造函数就一个,并且Bean定义的构造函数参数列表及传入的参数列表长度都为1,则直接实例化,并存入缓存:
if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Constructor> uniqueCandidate = candidates[0];
if (uniqueCandidate.getParameterCount() == 0) {
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
否则就需要解析每个构造函数,并进行排序和筛选,排序的标准是,优先public,同优先级构造函数根据参数列表长度降序排序(使用Arrays.sort,传入自定义比较器进行排序):
private static final Comparator EXECUTABLE_COMPARATOR = (e1, e2) -> {
boolean p1 = Modifier.isPublic(e1.getModifiers());
boolean p2 = Modifier.isPublic(e2.getModifiers());
if (p1 != p2) {
return (p1 ? -1 : 1);
}
int c1pl = e1.getParameterCount();
int c2pl = e2.getParameterCount();
return Integer.compare(c2pl, c1pl);
};
筛选的标准,首先是长度,比Bean定义中的长度,或者传入参数列表的长度还小,肯定是要跳过的:
if (paramTypes.length < minNrOfArgs) {
continue;
}
然后将getBean传入的explicitArgs对象,或者解析构造函数时生成的resolvedValues对象封装进ArgumentsHolder里,并比较当前遍历到的构造函数的参数列表长度、参数类型,与给定特征的差异,选取差异最小的一对 构造函数-参数,进行实例化并存入缓存:
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
if (typeDiffWeight < minTypeDiffWeight) {
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
}
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
...
if (explicitArgs == null && argsHolderToUse != null) {
argsHolderToUse.storeCache(mbd, constructorToUse);
}
如果一番比较之下,没有一个构造函数满足需求,则抛出异常。
以上三小节都是些特殊情形,对于普通的Bean,既没有工厂方法,也没有带参构造函数,Spring提供了instantiateBean方法来直接实例化。该方法实际上还是调用了SimpleInstantiationStrategy.instantiate方法,这次则是三参数版本。
到这里,createBeanInstance就执行完毕了。
createBeanInstance执行后,Bean实际上已经实例化了,不过假如程序员配置了一些后处理器等,会在此时生效,对Bean进行处理。
首先是使用注册到容器的PostProcessor处理Bean。applyMergedBeanDefinitionPostProcessors的逻辑就是遍历后处理器列表,调用MergedBeanDefinitionPostProcessor类型后处理器的postProcessMergedBeanDefinition方法:
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;
}
}
接下来,需要检查是否需要提前暴露当前正在创建的Bean,在本篇第一节提到,earlySingletonObjects存储了正在创建中的单例Bean,用来解决循环依赖问题,当被依赖的Bean执行完createBeanInstance后,就可以从earlySingletonObjects中移除:
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// in DefaultSingletonBeanRegistry.java
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);
}
}
}
earlySingletonExposure的三个条件,第一个和第三个不用多说,第二个只能通过AbstractRefreshableApplicationContext的setAllowCircularReferences()方法进行配置。addSingletonFactory最重要的作用是,记录了创建Bean的ObjectFactory。它的作用在属性填充时再解释。
然后再看下getEarlyBeanReference,该函数主要是调用SmartInstantiationAwareBeanPostProcessor的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;
}
该接口的一个用途是完成Advice的织入,在该接口的实现类AbstractAutoProxyCreator中,有如下代码:
// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
不过此时还不能添加到singletonObjects列表中,因为新创建的Bean还需要初始化:
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
...
}
populateBean对Bean实例进行属性填充,利用到了RootBeanDefinition中注册的属性。首先进行一次判断,假如传入的BeanWrapper是null,则无需进行填充。一般来说都不会出现这个情况,那么接着往下看。
在属性被赋给BeanWrapper前,还有一次通过InstantiationAwareBeanPostProcessor修改Bean的机会:
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
postProcessAfterInstantiation返回了布尔值,这里用于判断是否继续进行属性设置,如果返回false,则会在后处理器生效后直接退出属性填充步骤。否则开始进行属性填充,首先是根据autowire类型,提取依赖的Bean并存入PropertyValues中:
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
上面提到,autowire的默认值是no,不过还是看一下name和type的效果。
1)autowireByName:
首先是autowireByName:
protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
if (containsBean(propertyName)) {
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
registerDependentBean(propertyName, beanName);
}
}
}
这里通过遍历寻找BeanWrapper中需要依赖注入的属性,通过getBean获取,通过registerDependentBean注册依赖。将此处与doGetBean的getSingleton方法和addSingletonFactory方法结合来看,就清楚addSingletonFactory的作用了:当出现循环依赖时,由于populateBean调用了getBean,就可以获取ObjectFactory,由它产生对象实例,而非完整生成一遍实例,这样就避免了无限递归的出现。
2)autowireByType:
然后来看autowireByType,它的大体框架和autowireByName还是比较类似的,也是通过unsatisfiedNonSimpleProperties获取需要注入的属性,然后逐个注入,不同之处在于,这里不是通过名称直接getBean注入,而是通过类型匹配寻找Bean:
protected void autowireByType(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
Set autowiredBeanNames = new LinkedHashSet<>(4);
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
if (Object.class != pd.getPropertyType()) {
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
registerDependentBean(autowiredBeanName, beanName);
}
autowiredBeanNames.clear();
}
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
getWriteMethodParameter解析了setter方法的参数,并封装为DependencyDescriptor,然后传入resolveDependency方法以获取注入参数。该方法在autowireConstructor也遇到过,这里详细介绍一下。
3)doResolveDependency:
该方法位于DefaultListableBeanFactory,首先对Optional、ObjectFactory、javaxInjectProviderClass三种特殊类型进行了处理,分别返回了一种BeanObjectProvider,不过归根结底,还是调用了doResolveDependency方法。该方法首尾两端分别设置了一个注入点,然后尝试获取Shortcut,所谓Shortcut,其实就是缓存了的属性或对象,查看ShortcutDependencyDescriptor源码发现,这里实际还是调用了getBean方法:
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
假如不存在Shortcut,即依赖还没有解析过,就需要进行解析。首先根据AutowireCandidateResolver的getSuggestedValue方法获取值,AutowireCandidateResolver在容器中的默认实现是SimpleAutowireCandidateResolver,它在此方法中返回null,不过AutowireCandidateResolver的另一个实现类QualifierAnnotationAutowireCandidateResolver,为Spring提供了通过@Value设置值的能力:
protected Object extractValue(AnnotationAttributes attr) {
Object value = attr.get(AnnotationUtils.VALUE);
if (value == null) {
throw new IllegalStateException("Value annotation must have a value attribute");
}
return value;
}
假如getSuggestedValue返回值value不为空且为String类型,就可以用来判断是否包含在BeanDefinition中,是则解析为一个Expression对象。不过无论如何,都会在有必要的情况下尝试对value进行类型转换:
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
try {
return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
}
catch (UnsupportedOperationException ex) {
// A custom TypeConverter which does not support TypeDescriptor resolution...
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
}
假如value为空,也就是默认情况,或者没有配置@Value,则调用resolveMultipleBean对集合Bean进行解析,这里根据依赖类型分为不同分支,首先是stream类型的处理,这里挑选出了类型匹配的自动注入对象,通过它们的BeanName进行getBean,然后挑选出不是NullBean类型的实例:
Map matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
Stream
接下来是数组类型,这里对数组类型进行了解析,并以此获取自动注入的候选,然后调用类型转换器将数组转换为实际类型并排序:
Class> componentType = type.getComponentType();
ResolvableType resolvableType = descriptor.getResolvableType();
Class> resolvedArrayType = resolvableType.resolve(type);
if (resolvedArrayType != type) {
componentType = resolvableType.getComponentType().resolve();
}
if (componentType == null) {
return null;
}
Map matchingBeans = findAutowireCandidates(beanName, componentType,
new MultiElementDescriptor(descriptor));
if (matchingBeans.isEmpty()) {
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
Object result = converter.convertIfNecessary(matchingBeans.values(), resolvedArrayType);
if (result instanceof Object[]) {
Comparator
接下来的集合类型、Map类型就和数组类型比较像了,都是解析出泛型类型,然后进行类型匹配,寻找自动注入候选,只不过集合类型会对List实现类做一次排序,Map类型就没有这个过程。
通过上述源码,也解释了一个问题:resolveDependency用到了一个参数autowiredBeanNames,这里既然是靠类型匹配,为什么还需要名称?原来是依靠它解决泛型集合的类型匹配问题。
如果需要解析的复合类型,不是Stream、数组、集合、Map中的任何一种,则不考虑泛型,直接使用findAutowireCandidates根据类型匹配。假如匹配结果不唯一,还需要再进行筛选,否则经过验证就可以实例化、返回了。筛选标准有三:最优先的是primary属性为true的Bean,然后是优先级高的Bean(通过@Priority注解配置),最后是BeanName符合依赖描述的。假如经过筛选,仍然有多个Bean有着同样的优先度,则抛出异常。
4)应用PropertyValue
autowireByXX方法执行完后,实际已经完成了属性到PropertyValue的转换。在这之后,如果需要调用InstantiationAwareBeanPostProcessors或者进行依赖检查,则进行相应调用。然后把处理完毕的PropertyValue传入applyPropertyValues方法。
该方法的核心语句就一句:
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
调用setter进行赋值,不过在此之前进行了一系列判断和处理。
首先是防止重复转换的判断:
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property valus", ex);
}
}
original = mpvs.getPropertyValueList();
}
else {
original = Arrays.asList(pvs.getPropertyValues());
}
如果没有转换过,则遍历PropertyValue列表,使用TypeConverter和BeanDefinitionResolver进行值的解析和转换。
在Bean属性注入完毕后,就可以开始调用其init-method属性配置的初始化方法了。这一步在initializeBean方法完成。
该方法调用的关键方法有四个:
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
invokeAwareMethods(beanName, bean);
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
invokeInitMethods(beanName, wrappedBean, mbd);
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
return wrappedBean;
}
1)invokeAwareMethods
在之前我们也有接触过一些Aware接口的使用例子,例如 容器功能的扩展 中有看到EnvironmentAware、ResourceLoaderAware、ApplicationContextAware等接口的身影。Bean实现了Aware接口后,就可以通过setter方法获取Spring容器的资源。
不过此处只处理了BeanNameAware、BeanClassLoaderAware、BeanFactoryAware三种接口的实现类:
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
2)applyBeanPostProcessorsBeforeInitialization / applyBeanPostProcessorsAfterInitialization
以Before为例,实际就是遍历BeanPostProcessor列表,逐个调用而已。
3)invokeInitMethods
该方法调用了 invokeCustomInitMethod 方法,首先判断了一下是否配置了init-method属性,没有则抛出异常:
String initMethodName = mbd.getInitMethodName();
Assert.state(initMethodName != null, "No init method set");
final Method initMethod = (mbd.isNonPublicAccessAllowed() ?
BeanUtils.findMethod(bean.getClass(), initMethodName) :
ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
if (initMethod == null) {
if (mbd.isEnforceInitMethod()) {
throw new BeanDefinitionValidationException("Could not find an init method named '" +initMethodName + "' on bean with name '" + beanName + "'");
}
}
有则通过Method的invoke方法反射调用:
initMethod.invoke(bean);
同时还调用了所有实现了InitializingBean接口的实例的afterPropertiesSet方法:
((InitializingBean) bean).afterPropertiesSet();
假如之前经过判断,需要提前暴露,那么在Bean初始化完成后,就可以添加到earlySingletonObjects中,完成暴露了:
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.");
}
}
}
}
getSingleton方法将Bean添加到earlySingletonObjects中,并使用之前存储的ObjectFactory返回一个实例。然后检查实例在初始化方法中是否(通过BeanPostProcessor或自定义初始化方法)进行了增强(是否和原来的bean对象相同),如果没有进行增强,就可以直接下一步,否则还是要检查下依赖。
由于到这一步,Bean已经创建完毕,即属性注入成功,说明依赖的Bean应该也创建完毕了,假如actualDependentBeans不为空,说明还是有循环依赖情况,需要抛出异常。
运行到这里, 其实已经可以返回Bean了,不过Spring既然对初始化方法提供了扩展,肯定也对销毁方法做了扩展。这一步就是为了扩展销毁方法的。
源码本身并不复杂,如果Bean是prototype,本身是随用随创建,创建完毕后就不再管理,因此无需进行扩展,如果不需要扩展,那也没必要继续。
对于单例Bean,通过registerDisposableBean处理;对于其它scope的Bean,通过registerDestructionCallback处理。
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = System.getSecurityManager() != null ? this.getAccessControlContext() : null;
if (!mbd.isPrototype() && this.requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
this.registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, this.getBeanPostProcessors(), acc));
} else {
Scope scope = (Scope)this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, this.getBeanPostProcessors(), acc));
}
}
}
1)registerDisposableBean
实际就是把需要销毁、实现了DisposableBean接口的Bean放进一个Map里,Map中的Bean销毁时,对其使用DestructionAwareBeanPostProcessor的postProcessBeforeDestruction方法。
public void registerDisposableBean(String beanName, DisposableBean bean) {
synchronized (this.disposableBeans) {
this.disposableBeans.put(beanName, bean);
}
}
如果注册了多个DestructionAwareBeanPostProcessor,则挑选参数最少的那个:
private Method findDestroyMethod(String name) {
return (this.nonPublicAccessAllowed ?
BeanUtils.findMethodWithMinimalParameters(this.bean.getClass(), name) :
BeanUtils.findMethodWithMinimalParameters(this.bean.getClass().getMethods(), name));
}
2)registerDestructionCallback
这里以ServletContextScope类的实现为例,在该类中,有一个Map
调用它的destroy方法时,会逐个调用Map元素的run方法(实际就是DisposableBeanAdapter.destroy()方法,逻辑同上):
public void destroy() {
for (Runnable runnable : this.destructionCallbacks.values()) {
runnable.run();
}
this.destructionCallbacks.clear();
}
至此,createBean方法执行结束。
对于单例Bean,接下来还有getObjectForBeanInstance方法,该方法在上面已经介绍过了。
对于prototype和其它scope的Bean,还有beforePrototypeCreation、afterPrototypeCreation两个方法围绕在createBean周围,其实就是将PrototypeBean添加到正在创建队列和从队列移除。
最后,Spring再次检查了创建的Bean的类型和实际需要的类型是否匹配:
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
实际就是获取一个TypeConverter进行一次转换,通过查看TypeConverterDelegate的源码,可以发现,它调用了ConversionService的convert方法进行转换,如果convert方法无法转换,就应当返回null,这样Spring就能检测到创建出来的Bean不符合需要,从而抛出异常。