在上一篇中,分析了getBean()方法的详细流程,里面涉及到了单实例bean的创建,createBean(),本篇将分析这个方法,分析一下Spring中单实例对象时如何创建出来的。
1.createBean
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd,/*按照传递的参数构建bean的实例并且返回,一般很少使用到参数*/ @Nullable Object[] args)
throws BeanCreationException {
/*
* 创建实例使用的bean定义信息
* */
RootBeanDefinition mbdToUse = mbd;
/*
* 检查当前bean的定义信息是否有class信息,如果有的话返回class类型,如果没有的话,使用类加载器加载class实例加载到jvm,并返回class对象
*
* */
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
/*
* 条件一:拿到了bean定义信息 实例化时候需要的真实class对象
* 条件二:说明bean定义信息在解析bean对象之前(resolveBeanClass())是没有class对象的
* 条件三:说明mbd有className
*
* 都成立之后就会去重新初始化mbd对象,进行一层包装。
* */
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
/*
* 预处理 方法重写的逻辑。。 给重写的方法打一个标。
* */
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
/*
* 通过后置处理器在这里返回一个代理的实例对象
* 这里的代理对象不是spring 的 aop 的实现。
* 实例化之前 并不是init执行前后 后置处理器的执行机会
* */
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
/*如果对象不为空,直接返回。*/
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
/*
* 真正的创建bean的逻辑,spring里面真正干活的方法都是以do开头
* 创建bean实例 执行依赖注入 执行init 后置处理器的逻辑
* */
/**
* 1.第一次创建man的逻辑
* 2.创建women
*/
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
- 首先使用
**resolveBeanClass()**
解析出当前bean的类型 - 如果解析出的bean类型不为空,并且mbd里面没有bean的类型,并且mbd的className不为空
- 创建一个新的
**RootBeanDefinition**
,将Class类型设置进去
- 处理方法重写的逻辑
**prepareMethodOverrides()**
**resolveBeforeInstantiation() **
通过后置处理器在这里尝试返回一个代理对象,这里的代理并不是Aop的实现,此时是实例化之前,并不是**init()**
执行前后- 如果后置处理器成功返回了对象,直接返回
- 如果后置处理器没有返回一个代理对象,那就将创建bean的逻辑委派给
**doCreateBean()**
,返回创建好的bean实例对象。
按照执行流程来分析,我们先分析**resolveBeanClass()**
方法。
2.resolveBeanClass()
@Nullable
protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
throws CannotLoadBeanClassException {
try {
if (mbd.hasBeanClass()) {
return mbd.getBeanClass();
}
return doResolveBeanClass(mbd, typesToMatch);
}
catch (ClassNotFoundException ex) {
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
}
catch (LinkageError err) {
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
}
}
可以看到,这里其实又是一个委派模式。**doResolveBeanClass()**
。
@Nullable
private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
throws ClassNotFoundException {
ClassLoader beanClassLoader = getBeanClassLoader();
ClassLoader dynamicLoader = beanClassLoader;
boolean freshResolve = false;
if (!ObjectUtils.isEmpty(typesToMatch)) {
// When just doing type checks (i.e. not creating an actual instance yet),
// use the specified temporary class loader (e.g. in a weaving scenario).
ClassLoader tempClassLoader = getTempClassLoader();
if (tempClassLoader != null) {
dynamicLoader = tempClassLoader;
freshResolve = true;
if (tempClassLoader instanceof DecoratingClassLoader) {
DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
for (Class<?> typeToMatch : typesToMatch) {
dcl.excludeClass(typeToMatch.getName());
}
}
}
}
String className = mbd.getBeanClassName();
if (className != null) {
Object evaluated = evaluateBeanDefinitionString(className, mbd);
if (!className.equals(evaluated)) {
// A dynamically resolved expression, supported as of 4.2...
if (evaluated instanceof Class) {
return (Class<?>) evaluated;
}
else if (evaluated instanceof String) {
className = (String) evaluated;
freshResolve = true;
}
else {
throw new IllegalStateException("Invalid class name expression result: " + evaluated);
}
}
if (freshResolve) {
// When resolving against a temporary class loader, exit early in order
// to avoid storing the resolved Class in the bean definition.
if (dynamicLoader != null) {
try {
return dynamicLoader.loadClass(className);
}
catch (ClassNotFoundException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
}
}
}
return ClassUtils.forName(className, dynamicLoader);
}
}
// Resolve regularly, caching the result in the BeanDefinition...
return mbd.resolveBeanClass(beanClassLoader);
}
这里面没有什么核心的逻辑,不作具体分析。关注一下重要的逻辑,在bean实例创建之前尝试返回一个代理对象。
3.实例化之前尝试返回一个代理对象
**resolveBeforeInstantiation()**
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// hasInstantiationAwareBeanPostProcessors() 看当前需要执行的集合里面
//是否有相关的后置处理器,如果有的话,条件成立 ,才能执行if 里面的逻辑
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
/*
* 执行bean 实例化 前后的后置处理器 before 方法,默认是返回null,如果想要做特殊的逻辑处理
* 可以自己继承接口进行扩展。需要继承的接口:InstantiationAwareBeanPostProcessor
* */
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
/*
* 如果bean真的在这里创建出来了,那么,下面就会执行bean实例化后的后置处理器逻辑
* */
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
- 如果有
**InstantiationAwareBeanPostProcessors**
这个类型的后置处理器
- 获取被代理对象的类型
- 如果类型不为空
- 执行bean实例化前后的后置处理器的before(),默认是返回null。如果想要做特殊的逻辑处理,可以自己继承接口进行扩展。
**applyBeanPostProcessorsBeforeInstantiation()**
�
- 如果有特殊处理的逻辑,也就是返回了一个代理对象,那就执行bean实例化后的后置处理器方法。
**applyBeanPostProcessorsAfterInitialization()**
-
3.1 applyBeanPostProcessorsBeforeInstantiation()
、 @Nullable protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { Object result = bp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } return null; }
遍历所有的后置处理器,执行后置处理器的前置方法,如果某一个后置处理器返回了一个不为空的对象,直接返回该对象,后面的后置处理器的方法不在执行。
3.2 applyBeanPostProcessorsAfterInitialization()
@Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); /*注意: * 一旦某个后置处理器返回的结果为空 * 就返回上一个后置处理器的结果,后面的后置处理器方法不在执行*/ if (current == null) { return result; } result = current; } return result; }
遍历所有的后置处理器,执行后置处理器的后置方法,如果某一个后置处理器返回了null,直接返回null,后面的后置处理器的方法不在执行。
**InstantiationAwareBeanPostProcessors**
的逻辑可以看前面的Spring组件与注解篇,再次不再赘述。
4.doCreateBean()
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// BeanWrapper:一个包装的bean实例,继承了可配置的属性访问器
BeanWrapper instanceWrapper = null;
/*如果是单实例bean对象,清理缓存并返回该对象,这里正常情况下是拿不到的,因为还未创建bean对象实例。*/
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
/*如果上面的逻辑没拿到,说明还是正常的逻辑,执行创建bean实例的方法并且包装到wrapper中。*/
if (instanceWrapper == null) {
/**
* 1.第一次走到这里是去创建man
* 2.创建women
*/
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
/*获取包装好的bean实例对象*/
Object bean = instanceWrapper.getWrappedInstance();
/*拿到bean实例的Class类型*/
Class<?> beanType = instanceWrapper.getWrappedClass();
/*如果bean类型不为空,将bean类型设置到mergedBeanDefinition中*/
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
/*允许post-processors 在此刻对 merged bean definition 进行修改*/
synchronized (mbd.postProcessingLock) {
/*如果后置处理器的逻辑还尚未执行,那就在此刻执行,执行之后将是否执行过修改为true,这也就限定了后置处理器只能执行一次。*/
if (!mbd.postProcessed) {
try {
/*执行后置处理器的核心逻辑:合并bd信息,接下来就是populate处理依赖。*/
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
/*
* 提前地缓存单例,以便能够解析循环引用,即使被生命周期接口(如BeanFactoryAware)触发。
* 其实这里的逻辑就是判断是否过早的暴露早期的bean实例,已经初始化,但是没实例化。
* */
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
/*如果支持早期暴露单实例bean对象*/
if (earlySingletonExposure) {
/*日志打印*/
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
/*加入到单例bean工厂,将早期bean'实例(已经实例化但是尚未初始化)的引用加入到第三级缓存
* getEarlyBeanReference()*/
/**
* 1.man现在刚创建出来,还没有进行属性赋值和初始化,此时将他放到第三级缓存
* 2.此时的women也是通过反射刚刚创建出来,还没有进行属性赋值和初始化的逻辑,此时把他放到了三级缓存中
*/
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
/*对bean进行属性赋值,依赖注入。*/
/**
* 1.对man进行属性赋值
* 2.对women进行属性赋值
*/
populateBean(beanName, mbd, instanceWrapper);
/*生命周期中的初始化方法的调用*/
/**
* 1.women先经过这里
*/
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);
//条件成立:说明当前bean实例是从二级缓存就获取到了
//说明产生了,循环依赖,三级缓存 当前对象的ObjectFactory.getObject()被调用过
if (earlySingletonReference != null) {
/*什么时候相等呢?
* 1.当前的真实实例不需要被代理
* 2.当前实例已经被代理过,,,是在ObjectFactory.getObject()方法调用的时候,实现的增强代理*/
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
/*获取依赖当前bean的其他beanName*/
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
/*如果依赖当前bean的bean已经创建完了,就把他加入到集合中去*/
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
/*当前bean正在创建,但是依赖当前bean的bean已经创建完了,那说明指定是有问题,不对劲。*/
/**
* 为什么有问题?
* 因为当前对象的aop操作是在当前方法 initbean 完成的
* 在这之前 ,外部其他bean持有的当前bean实例 都是尚未增强的。
*/
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 " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
/*判断当前bean是否需要注册一个容器关闭时候的析构函数回调*/
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
- 如果是单实例bean对象,拿到该对象,并清理缓存,这里正常情况下是什么都拿不到的,因为还没有创建bean对象实例。
- 如果上面的逻辑什么也没有拿到,说明还是正常的情况,执行创建bean实例的方法并且包装到wrapper中。
**createBeanInstance()**
- 获取包装好的bean实例对象,拿到bean实例对象的class类型,将他设置到mbd中。
- 在属性赋值之前,给尚未执行的后置处理器最后一次机会来执行,执行之后修改执行过状态为true,这也就限定了后置处理器只能执行一次。
**applyMergedBeanDefinitionPostProcessors()**
- 判断是否允许过早的暴露早期bean实例的引用(已经初始化,但是尚未实例化)
- 将早期bean实例加入到三级缓存
- 对早期暴露的bean进行属性赋值
**populateBean()**
- 在属性赋值之后执行bean对象的初始化方法
**initializeBean()**
- 这里开始其实就是循环依赖的逻辑,首先判断是不是允许早期暴露的单实例bean对象,如果是的话
- 从缓存中拿到尝试获取bean,
**getSingleton()**
- 如果从缓存拿到bean了,说明当前bean实例是从二级缓存就获取到了,说明产生了循环依赖
- 如果依赖于当前bean其他bean对象,,如果依赖当前bean的对象都已经创建完了,那就吧他们加入到集合中。
当前bean正在创建,但是依赖他的bean都创建完了,那就说明逻辑上出现问题了
为什么会出现问题? 因为当前对象的aop操作是在当前方法的init方法里面执行的,在这之前,其他对象拿到的bean都是尚未增强的bean。
判断当前bean是否需要注册一个容器关闭时候执行的析构函数
**registerDisposableBeanIfNecessary()**
�
�这里面其实主要关注五个点:**createBeanInstance()**
,**applyMergedBeanDefinitionPostProcessors()**
,**populateBean()**
,**initializeBean()**
,**registerDisposableBeanIfNecessary()**
。
5.createBeanInstance()
使用适当的实例化策略为指定的 bean 创建一个新实例:工厂方法,构造函数自动装配或简单实例化。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 解析bean定义信息中的 bean 的实例类型
Class<?> beanClass = resolveBeanClass(mbd, beanName);
/*
* 条件一:Class 实例不为空
* 条件二:Class实例的访问权限不是公开的
* 条件三:CLass实例的权限没打开,没打开就不能反射我记得。
* */
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
/*spring5新特性,没研究*/
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
/*说明bean标签配置了 factoryMethod属性:利用工厂创建对象的逻辑。*/
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 创建相同bean的时候,可以走捷径。解析构造器比较耗时,所以如果一个对象创建两次,可以不用那么麻烦。
/*
* resolved:bd对应的构造信息是否已经解析成可以发射调用的构造方法信息
* autowireNecessary:是否自动匹配构造方法
*
* */
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
/*
* mbd.resolvedConstructorOrFactoryMethod != null
* 条件成立:说明bd的构造信息已经转化成可以反射调用的method,并且被缓存。
* */
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
/*说明已经解析过*/
resolved = true;
/*判断构造方法的参数是否已经被解析了,resolvedConstructorOrFactoryMethod 有值
* 且构造方法有参数,可以认为字段值就是true
* 设么情况下为false?
* 1.resolvedConstructorOrFactoryMethod == null
* 2.当resolvedConstructorOrFactoryMethod 表示的是默认的无参构造器的时候
* */
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
/*
* 如果已经解析过,
*
* */
if (resolved) {
/*并且可以自动匹配构造方法*/
if (autowireNecessary) {
/*自动匹配有参构造器*/
return autowireConstructor(beanName, mbd, null, null);
}
/*没有参数解析,也就是无参构造方法处理*/
else {
/**
* 1.第一次去创建man
* 2.创建women
*/
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
/**
* 后置处理器的调用点:SmartInstantiationAwareBeanPostProcessor
* 这个后置处理器里面默认是实现方法为空,想要执行这里的逻辑可以自己继承接口实现
*
* 典型应用 @Autowired 打在了构造器方法上,就会用到后置处理器 AutowiredAnnotationBeanPostProcessor
*/
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
/*
* 条件1:后置处理器指定了构造方法数组
* 条件2:一般不会成立。bean标签里面配置了autowired=constructor 才会触发
* 条件3:说明bean标签中配置了构造参数信息
* 条件4:getBean时,args有参数
* */
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
/*判断是否在beanDefinition里面配置偏好构造器,默认实现是null。*/
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
/*大部分情况下都是走这里:未指定构造参数,未设定偏好,使用无参构造器创建bean实例。*/
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}
- 解析bd中的bean类型
- 对类型做一些校验
- 判断如果配置了bean标签里面的
**factoryMethod**
属性,走利用工厂创建对象的逻辑。**instantiateUsingFactoryMethod()**
- 进行一些属性判断,其实主要就是创建相同bean对象的时候,没有必要全部重新来做,可以走一些捷径
- 如果已经解析过&可以自动匹配构造方法,那就走自动匹配有参构造器的逻辑。
**autowireConstructor()**
- 如果是已经解析过&无参构造器的处理方法,那就走
**instantiateBean()**
接下来是一个后置处理器的调用点
_**SmartInstantiationAwareBeanPostProcessor**_
,这个后置处理器里面默认实现为空,可以自己扩展。典型的应用就是 @Autowired 注解打在了构造器上,就会用到后置处理器
_**AutowiredAnnotationBeanPostProcessor**_
。判断是否需要执行构造器自动注入的逻辑
**autowireConstructor()**
- 判断是否在beandefinition里面配置了偏好的构造器,默认实现是null,如果是的话,就走
**autowireConstructor()**
。 - 大部分情况下,其实会走
**instantiateBean()**
。(未指定构造参数,未设置偏好,使用无参构造器创建bean对象实例)
�
这里主要关心三个方法**instantiateBean()**
&**autowireConstructor()**
&**instantiateUsingFactoryMethod()**
。
5.1 instantiateBean()
�
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
/*获取实例化策略,调用实例化方法创建bean实例*/
/**
* 1.反射去创建man
* 2.反射去创建women
*/
Object beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
/*根据实例创建bean实例的包装器*/
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
/*对包装器进行一些参数,工具设置*/
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
首先获取到实例化的策略,反射去创建对象,根据bean去创建对象的包装器,对包装器进行赋能。**instantiate()**
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
/*不考虑方法覆盖*/
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
constructorToUse = clazz.getDeclaredConstructor();
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
/*实例化*/
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
/*方法覆盖的逻辑*/
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
**instantiateClass()**
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
ReflectionUtils.makeAccessible(ctor);
if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
return KotlinDelegate.instantiateClass(ctor, args);
}
else {
Class<?>[] parameterTypes = ctor.getParameterTypes();
Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
/*这里的参数数组是为了防止某个类型传过来的值是null,如果是null,就是用默认的值*/
Object[] argsWithDefaultValues = new Object[args.length];
for (int i = 0 ; i < args.length; i++) {
if (args[i] == null) {
Class<?> parameterType = parameterTypes[i];
/*从这里就能看到是不是选用了默认值*/
/*
* DEFAULT_TYPE_VALUES :存各种基本数据类型的默认值。
* */
argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
}
else {
argsWithDefaultValues[i] = args[i];
}
}
/*通过构造器来进行反射实例化创建bean实例。*/
return ctor.newInstance(argsWithDefaultValues);
}
}
catch (InstantiationException ex) {
throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
}
catch (InvocationTargetException ex) {
throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
}
}
5.2autowireConstructor()
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
/*通过构造函数解析器的autowireConstructor方法来创建bean实例*/
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
自动装配构造函数行为。如果指定了显式的构造函数参数值,也可以,将所有剩余参数与来自bean工厂的bean匹配。这块对应于构造函数注入,在这种模式下spring的bean工厂能够承载期望基于构造函数的依赖项解析的组件。**autowireConstructor()**
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
/*创建了一个bean包装器的实例*/
BeanWrapperImpl bw = new BeanWrapperImpl();
/*初始化bean包装器*/
this.beanFactory.initBeanWrapper(bw);
/*最终反射调用的构造器*/
Constructor<?> constructorToUse = null;
/*holder持有的是:实例化的时候,真正用到的参数*/
ArgumentsHolder argsHolderToUse = null;
/*实例化的时候使用到的参数*/
Object[] argsToUse = null;
/*如果getbean传的参数不为空,使用到的参数就是指定的参数*/
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {/*getBean的时候没有指定参数*/
/*表示构造器参数需要做类型转换,参数引用*/
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
/*到缓存去看看有没有缓存过构造器*/
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
/*缓存有解析好的构造器并且构造器参数已经被解析过 说明不是第一次通过bd生成实例*/
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached constructor...
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
/*条件成立说明:resolvedConstructorArguments==null*/
if (argsToResolve != null) {
/*解析构造参数*/
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
}
}
/*条件成立说明缓存机制失败,或者是第一次创建,需要匹配构造器。*/
if (constructorToUse == null || argsToUse == null) {
// Take specified constructors, if any.
/*chosenCtors什么时候有值呢?构造器上有@Autowired注解的时候。*/
Constructor<?>[] candidates = chosenCtors;
/*条件成立说明:外部程序调用方法的时候并没有指定可选用的构造器,需要通过class拿到构造器信息*/
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
try {
/*如果非公开的方法也允许访问就获取所有的构造器,否则获取可以访问的构造器。*/
candidates = (mbd.isNonPublicAccessAllowed() ?
beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
}
/*执行到这里,可选用的构造器列表已经转备好了,但是还没确定具体是哪一个*/
/*如果只有一个构造器并且getBean没有指定构造器参数,并且bean定义信息里面没有参数,那就是用默认的无参构造器*/
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;
}
}
// 需要解析到底是用哪一个构造器
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
/*完成解析后的构造器参数值列表*/
ConstructorArgumentValues resolvedValues = null;
/*构造器参数的个数*/
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
/*从beanDefinition拿到构造器参数*/
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
/*将此 bean 的构造函数参数解析为 resolveValues 对象。 这可能涉及查找其他 bean。
此方法也用于处理静态工厂方法的调用。,*/
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
/*给可选用的构造器数组排序,排序规则: public > no public more args > no args*/
AutowireUtils.sortConstructors(candidates);
/*这个值越低,说明当前构造器参数列表类型和构造参数的匹配值越高*/
int minTypeDiffWeight = Integer.MAX_VALUE;
/*尚未筛选或者筛选完还未确定的构造器*/
Set<Constructor<?>> ambiguousConstructors = null;
Deque<UnsatisfiedDependencyException> causes = null;
/*筛选可选的构造方法,找出一个匹配度最高的构造函数*/
for (Constructor<?> candidate : candidates) {
/*获取当前处理的构造器参数个数*/
int parameterCount = candidate.getParameterCount();
/*这里判断的指标都是上面循环筛选出来的东西
* 因为candidates是排过序的 排序规则:public > no public > 多参数的 > 参数少的
* 当前筛选出来的构造器优先级一定是优先于后面的构造器的
* */
if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
break;
}/*表示当前构造器参数 小于 bd中配置了构造器参数个数,说明匹配不上。*/
if (parameterCount < minNrOfArgs) {
continue;
}
/*构造器参数的持有对象*/
ArgumentsHolder argsHolder;
/*拿到当前构造器的参数类型数组*/
Class<?>[] paramTypes = candidate.getParameterTypes();
/*已经解析后的构造器参数值不为空,说明bd中是有参数的,需要做匹配逻辑*/
if (resolvedValues != null) {
try {
/*根据构造器参数注解@ConstructorProperties拿到所有参数的名字*/
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
/*如果数组的名字是空,那么就都是默认的名字*/
if (paramNames == null) {
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
}
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
}
catch (UnsatisfiedDependencyException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next constructor.
if (causes == null) {
causes = new ArrayDeque<>(1);
}
causes.add(ex);
continue;
}
}
else {
// Explicit arguments given -> arguments length must match exactly.
if (parameterCount != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
}
/*typeDiffWeight数值越高说明构造器与参数的匹配度越低。
* 计算出当前构造器参数类型与当前构造器参数匹配度*/
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;
}
/*条件成立说明:当前处理的构造器 他计算出来的typeDiffWeight值与上一次筛选出来的最优先的构造器的值一致,有模棱两可的情况。加入到模棱两可集合。*/
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}
/*条件成立:没找到可用构造器,所以直接报错。*/
if (constructorToUse == null) {
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Could not resolve matching constructor on bean class [" + mbd.getBeanClassName() + "] " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
}
/*条件成立:模棱两可的构造器集合有值,并且beanDefinition里面的构造器指定策略是狭窄策略,这个时候也要报错。*/
else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous constructor matches found on bean class [" + mbd.getBeanClassName() + "] " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousConstructors);
}
/*条件成立:说明自动匹配成功了,需要进行缓存,方便后来者继续使用mergerdbeanDefinition来创建实例*/
if (explicitArgs == null && argsHolderToUse != null) {
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
Assert.state(argsToUse != null, "Unresolved constructor arguments");
/*根据上面选择的构造器和解析出来的参数,通过instantiate方法反射创建bean对象实例,最终将实例设置到beanWrapper的beanInstance实例里面。*/
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}
5.3 instantiateUsingFactoryMethod()
protected BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
//工厂模式创建对象的方法
return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}
**instantiateUsingFactoryMethod()**
public BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
//创建一个空的bean实例的包装器
BeanWrapperImpl bw = new BeanWrapperImpl();
//进行一些参数设置,给包装器赋能
this.beanFactory.initBeanWrapper(bw);
//工厂bean对象的引用
Object factoryBean;
//工厂bean对象的类型
Class<?> factoryClass;
//是不是静态工厂
boolean isStatic;
//获取工厂bean的名字
String factoryBeanName = mbd.getFactoryBeanName();
//如果工厂bean的名字不为空
if (factoryBeanName != null) {
//如果工厂bean的名字和要创建的bean名字一样,那么说明出现问题了,这个时候要抛异常
if (factoryBeanName.equals(beanName)) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
"factory-bean reference points back to the same bean definition");
}
//获取工厂bean对象
factoryBean = this.beanFactory.getBean(factoryBeanName);
//如果mbd是单实例的 && 当前一级缓存里面包含这个要创建的单实例bean
//这个时候说明不正常,为啥呢?我们要通过工厂模式创建的bean,被以其他方式创建出来了,非正常途径得到的bean
if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
throw new ImplicitlyAppearedSingletonException();
}
//给当前要创建的bean实例对象注册一个依赖bean,这个依赖bean就是他的工厂bean
this.beanFactory.registerDependentBean(factoryBeanName, beanName);
factoryClass = factoryBean.getClass();
isStatic = false;
} //走到这里的情况就是工厂bean没有名字,什么情况会走到这里?通过静态工厂来创建对象
else {
// It's a static factory method on the bean class.
//如果依赖静态工厂来创建bean实例对象的话,那么必须要有工厂bean的类型,否则没法创建
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;
}
//创建bean对象的工厂方法
Method factoryMethodToUse = null;
//持有创建对象需要的参数
ArgumentsHolder argsHolderToUse = null;
//创建对象需要使用的参数
Object[] argsToUse = null;
//getBean()方法传入的参数
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {//这里的逻辑就是getBean()的时候没有参数传递进来
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
//获取已经解析过的工厂方法
factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
//如果工厂方法已经解析过,&& mbd的构造器参数也已经解析过
if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached factory method...
//这里应该就是判断构造器参数有没有解析过,没有解析过的话,就去设置解析状态为准备解析
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
//判断构造器参数尚未解析过,就去解析构造器参数
if (argsToResolve != null) {
argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve);
}
}
//如果工厂方法为空 || 需要使用的参数为空
if (factoryMethodToUse == null || argsToUse == null) {
// Need to determine the factory method...
// Try all methods with this name to see if they match the given arguments.
//需要一个一个方法尝试,去找到创建bean所需要的工厂方法
factoryClass = ClassUtils.getUserClass(factoryClass);
List<Method> candidates = null;
//如果工厂方法是唯一的 && 当前尚未有指定工厂方法
if (mbd.isFactoryMethodUnique) {
if (factoryMethodToUse == null) {
//获取mbd里面已经解析过的工厂方法
factoryMethodToUse = mbd.getResolvedFactoryMethod();
}
//如果mbd里面有已经解析好的工厂方法,把他放到集合
if (factoryMethodToUse != null) {
candidates = Collections.singletonList(factoryMethodToUse);
}
}
//如果方法列表为空,有什么情况?
//可能是上面mbd里面没有已经指定的工厂方法
//也可能是工厂方法不是唯一的,一个类有多个工厂方法,这个时候工厂方法的名字都是一样的,只是方法形参不同
if (candidates == null) {
candidates = new ArrayList<>();
//拿到工厂里面的所有的方法
Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
//循环遍历,将满足条件的方法加入到集合
//满足什么条件? 是静态的方法 && 名字是指定的工厂方法的名字
for (Method candidate : rawCandidates) {
if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
candidates.add(candidate);
}
}
}
/*执行到这里,其实可选用的方法列表已经都帅选出来了,但是还没有具体确定是哪一个*/
//如果恰好只匹配到一个方法 && 参数为空 && 要创建的单实例bean 的构造参数也为空 ,那这里就是使用无参构造器的情况
if (candidates.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
//将这个方法指定为唯一的工厂方法
Method uniqueCandidate = candidates.get(0);
//如果工厂方法没有形参
if (uniqueCandidate.getParameterCount() == 0) {
//将mbd的工厂方法指定为这个方法
mbd.factoryMethodToIntrospect = uniqueCandidate;
//设置一些参数,给工厂方法创建对象赋能
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
//通过这个匹配到的工厂方法 ,利用 无参的工厂方法/构造器创建对象
//其实本质上还是利用反射调用工厂bean的工厂方法
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
//如果匹配到了多个方法 ,对匹配到的方法进行一个排序 排序规则 : public > no public && more args > no args
if (candidates.size() > 1) { // explicitly skip immutable singletonList
candidates.sort(AutowireUtils.EXECUTABLE_COMPARATOR);
}
//构造参数
ConstructorArgumentValues resolvedValues = null;
//已解析的自动装配代码 == 指示自动装配可以满足的最贪婪的构造函数的常量
//需要解析到底是哪一个方法
boolean autowiring = (mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
//选择权重 值越低,表示匹配度越高
int minTypeDiffWeight = Integer.MAX_VALUE;
//模棱两可的构造器集合
Set<Method> ambiguousFactoryMethods = null;
//通过getBean()传入的参数的个数/构造器参数的个数
int minNrOfArgs;
//如果通过getBean()传入的参数不为空 ,获取参数的个数
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
//
// getBean()没有传入参数,这种情况下,我们就得自己去解析bd里面的构造器
if (mbd.hasConstructorArgumentValues()) {
//从bd去拿到构造器
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
//将当前bean的方法参数或构造器参数解析 ,这里可能涉及到查找其他bean
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
else {//这就是无参构造器的情况
minNrOfArgs = 0;
}
}
Deque<UnsatisfiedDependencyException> causes = null;
//遍历匹配到的多个方法
for (Method candidate : candidates) {
//获取方法的参数个数
int parameterCount = candidate.getParameterCount();
/*这里判断的指标都是上面循环筛选出来的东西
* 因为candidates是排过序的 排序规则:public > no public > 多参数的 > 参数少的
* 当前筛选出来的构造器优先级一定是优先于后面的构造器的
* */
if (parameterCount >= minNrOfArgs) {
ArgumentsHolder argsHolder;
//进行类型匹配
Class<?>[] paramTypes = candidate.getParameterTypes();
//如果显式参数不为空
if (explicitArgs != null) {
// bd中的参数个数 和 当前给定的参数个数匹配不上 ,直接淘汰当前方法
if (paramTypes.length != explicitArgs.length) {
continue;
}
//将显式参数放到holder里面
argsHolder = new ArgumentsHolder(explicitArgs);
}
else {//这里是显式参数为空的情况
// 已解析的构造函数参数:需要类型转换和/或自动注入
try {
//存放方法的参数名数组
String[] paramNames = null;
//参数解析器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
//解析方法的参数名字
paramNames = pnd.getParameterNames(candidate);
}
//对参数进行封装
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw,
paramTypes, paramNames, candidate, autowiring, candidates.size() == 1);
}
catch (UnsatisfiedDependencyException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Ignoring factory method [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next overloaded factory method.
if (causes == null) {
causes = new ArrayDeque<>(1);
}
causes.add(ex);
continue;
}
}
//计算当前方法参数和当前方法的匹配度
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// 条件成立,说明本次的匹配度高于上一轮
if (typeDiffWeight < minTypeDiffWeight) {
factoryMethodToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousFactoryMethods = null;
}
/*
* 了解模糊性:对于具有相同参数数量的方法,如果存在相同类型的差异权重,则收集这样的候选项,并最终引发模糊性异常。
* 但是,只在非宽松的构造函数解析模式下执行该检查,并显式忽略重写的方法(具有相同的参数签名)。
* */
/*条件成立说明:当前处理的构造器 他计算出来的typeDiffWeight值与上一次筛选出来的最优先的构造器的值一致,有模棱两可的情况。加入到模棱两可集合*/
else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight &&
!mbd.isLenientConstructorResolution() &&
paramTypes.length == factoryMethodToUse.getParameterCount() &&
!Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {
//如果模棱两可的构造方法为空,就创建一个新的集合, 把满足条件的 构造器收集起来
if (ambiguousFactoryMethods == null) {
ambiguousFactoryMethods = new LinkedHashSet<>();
ambiguousFactoryMethods.add(factoryMethodToUse);
}
//保存模棱两可的构造方法
ambiguousFactoryMethods.add(candidate);
}
}
}
//如果要使用的工厂方法为空 或 要使用的参数为空,意思就是没找到创建对象的方法,那就得报错了;
if (factoryMethodToUse == null || argsToUse == null) {
//如果有异常信息,记录异常信息
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
List<String> argTypes = new ArrayList<>(minNrOfArgs);
//走到这里就是可用的方法为空,参数不为空
if (explicitArgs != null) {
//保存参数类型
for (Object arg : explicitArgs) {
argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
}
}
//如果构造器解析出的参数不为空,记录构造器参数的类型
else if (resolvedValues != null) {
Set<ValueHolder> valueHolders = new LinkedHashSet<>(resolvedValues.getArgumentCount());
valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
valueHolders.addAll(resolvedValues.getGenericArgumentValues());
for (ValueHolder value : valueHolders) {
String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType()) :
(value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null"));
argTypes.add(argType);
}
}
//否则就要抛出异常了
String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes);
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"No matching factory method found on class [" + factoryClass.getName() + "]: " +
(mbd.getFactoryBeanName() != null ?
"factory bean '" + mbd.getFactoryBeanName() + "'; " : "") +
"factory method '" + mbd.getFactoryMethodName() + "(" + argDesc + ")'. " +
"Check that a method with the specified name " +
(minNrOfArgs > 0 ? "and arguments " : "") +
"exists and that it is " +
(isStatic ? "static" : "non-static") + ".");
}
//如果工厂方法没有返回值,那指定不对,抛异常
else if (void.class == factoryMethodToUse.getReturnType()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Invalid factory method '" + mbd.getFactoryMethodName() + "' on class [" +
factoryClass.getName() + "]: needs to have a non-void return type!");
}
//如果模棱两可的方法不为空,抛异常
else if (ambiguousFactoryMethods != null) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous factory method matches found on class [" + factoryClass.getName() + "] " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousFactoryMethods);
}
/*条件成立:说明自动匹配成功了,需要进行缓存,方便后来者继续使用mergerdbeanDefinition来创建实例*/
if (explicitArgs == null && argsHolderToUse != null) {
mbd.factoryMethodToIntrospect = factoryMethodToUse;
argsHolderToUse.storeCache(mbd, factoryMethodToUse);
}
}
/*根据上面选择的构造器和解析出来的参数,通过instantiate方法反射创建bean对象实例,最终将实例设置到beanWrapper的beanInstance实例里面。*/
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
return bw;
}
6.applyMergedBeanDefinitionPostProcessors()
�
遍历所有的后置处理器进行方法调用,典型应用:如果开启了自动依赖注入,那么就会将相关的bean加入到集合中。
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
/*这里是后置处理器中的方法执行的逻辑
* 做了一件事情:提取出当前beanType类型整个继承体系内的@Autowired @Value @Inject 信息 并且包装成一个InjectionMetadata的一个对象
* 存放到 AutowiredAnnotationBeanPostProcessor 的缓存中,key是beanName。
* */
processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
**MergedBeanDefinitionPostProcessor**
7.registerDisposableBeanIfNecessary()
判断当前bean是否需要注册一个需要在容器关闭的时候执行的析构函数
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
/*条件一:原型模式的bean不会注册析构函数
* 条件二:判断当前bean是否需要注册析构函数*/
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
/*如果当前bean对象时单例模式*/
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
/*给当前单实例bean注册回调适配器。适配器内 根据当前bean实例是继承接口还是通过自定义来决定具体调用哪个方法,完成析构操作。*/
registerDisposableBean(beanName, new DisposableBeanAdapter(
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware));
}
else {
/*这是自定义作用域的逻辑,压根用不到*/
// A bean with a custom 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, getBeanPostProcessorCache().destructionAware));
}
}
}
首先会进行条件过滤,原型模式的bean排除,不需要注册的bean排除,我们只关心单实例bean的注册逻辑,其他作用域的处理逻辑不需要关注,判断如果是单实例bean对象,给当前的bean对象注册回调适配器。在适配器里面根据当前bean实例是继承接口还是通过自定义来决定具体调用哪个方法完成析构操作。
**DisposableBeanAdapter**
�
@Override
public void run() {
destroy();
}
@Override
public void destroy() {
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
processor.postProcessBeforeDestruction(this.bean, this.beanName);
}
}
if (this.invokeDisposableBean) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");
}
try {
((DisposableBean) this.bean).destroy();
}
catch (Throwable ex) {
String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
if (logger.isDebugEnabled()) {
logger.warn(msg, ex);
}
else {
logger.warn(msg + ": " + ex);
}
}
}
if (this.destroyMethod != null) {
invokeCustomDestroyMethod(this.destroyMethod);
}
else if (this.destroyMethodName != null) {
Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
if (methodToInvoke != null) {
invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
}
}
}
总结一下,其实就是创建对象的时候分为三种情况:无参构造器,有参构造器,工厂方法,创建完对象之后,在执行对应的后置处理器(**MergedBeanDefinitionPostProcessor**
),
最终在判断创建的bean实例是不是需要注册一个析构函数,在容器关闭的时候回调,如果需要就创建并保存。