Spring源码学习(五):Bean的创建和获取

目录

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方法。

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.postProcessBeforeInstantiation(beanClass, beanName);
				if (result != null) {
					return result;
				}
			}
		}
		return null;
	}

后者的逻辑和applyBeanPostProcessorsBeforeInstantiation相似,只是变成调用BeanPostProcessor的postProcessAfterInitialization方法。

2.2 创建Bean:doCreateBean的createBeanInstance方法

接下来,就是真正创建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);
}

2.2.1 通过Supplier实例化 —— obtainFromSupplier

首先了解下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)));
	}
}

2.2.2 通过factory-method实例化 —— instantiateUsingFactoryMethod

此处可以看出,要初始化的并不是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);

然后就可以根据解析出来的参数列表找到匹配的方法重载版本了。匹配方法有以下情形:

  • 方法没有重载版本,未配置参数,且方法参数列表长度为0,则直接实例化幷包装进BeanWrapper并返回
  • 方法有重载版本,则分析方法各版本参数列表的差异,取差异度最小的版本,实例化幷包装进BeanWrapper并返回

在代码中也可以看到,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);
    ...
}

2.2.3 自动绑定构造函数 —— autowireConstructor

调用该方法有以下情形:

  • RootBeanDefinition的构造函数参数已经解析过了,即具备找到合适构造方法的条件
  • 借助PostProcessor决定了需要绑定的构造函数
  • 没有更高优先度的构造方法

对于第二种情形,源码如下,实际就是遍历并找到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共有以下几种可选项:

  • no: 默认项,即不进行自动装配,只能通过ref属性引用其它bean。
  • byName: 在容器中根据BeanName进行查找并装配。
  • byType: 在容器中根据Bean的类型进行查找并装配。
  • constructor: 以byType的方式查找bean的构造参数列表。
  • default: 使用父元素的配置。

现在可以来看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> 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);
}

如果一番比较之下,没有一个构造函数满足需求,则抛出异常。

2.2.4 普通Bean的实例化 —— instantiateBean

以上三小节都是些特殊情形,对于普通的Bean,既没有工厂方法,也没有带参构造函数,Spring提供了instantiateBean方法来直接实例化。该方法实际上还是调用了SimpleInstantiationStrategy.instantiate方法,这次则是三参数版本。

到这里,createBeanInstance就执行完毕了。

2.3 Bean创建后的后处理:doCreateBean的剩余部分

createBeanInstance执行后,Bean实际上已经实例化了,不过假如程序员配置了一些后处理器等,会在此时生效,对Bean进行处理。

2.3.1 调用PostProcessor

首先是使用注册到容器的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;
    }
}

2.3.2 提前暴露

接下来,需要检查是否需要提前暴露当前正在创建的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) {
    ...
}

2.3.3 属性填充

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<String> 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<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (autowiredBeanNames != null) {
	autowiredBeanNames.addAll(matchingBeans.keySet());
}
Stream<Object> stream = matchingBeans.keySet().stream()
		.map(name -> descriptor.resolveCandidate(name, type, this))
		.filter(bean -> !(bean instanceof NullBean));
if (((StreamDependencyDescriptor) descriptor).isOrdered()) {
	stream = stream.sorted(adaptOrderComparator(matchingBeans));
}
return 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<String, Object> 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<Object> comparator = adaptDependencyComparator(matchingBeans);
    if (comparator != null) {
		Arrays.sort((Object[]) result, comparator);
	}
}
return result;

接下来的集合类型、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进行值的解析和转换。

2.2.4 Bean的初始化

在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)invokeAwareMethods

该方法调用了 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);

2.3.5 继续处理提前暴露

假如之前经过判断,需要提前暴露,那么在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<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.");
             }
         }
    }
}

getSingleton方法将Bean添加到earlySingletonObjects中,并使用之前存储的ObjectFactory返回一个实例。然后检查实例在初始化方法中是否(通过BeanPostProcessor或自定义初始化方法)进行了增强(是否和原来的bean对象相同),如果没有进行增强,就可以直接下一步,否则还是要检查下依赖。

由于到这一步,Bean已经创建完毕,即属性注入成功,说明依赖的Bean应该也创建完毕了,假如actualDependentBeans不为空,说明还是有循环依赖情况,需要抛出异常。

2.3.6 Bean转化为DisposableBean

运行到这里, 其实已经可以返回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<String,Runnable>类型的成员变量destructionCallbacks,在registerDestructionCallback方法中,将传入的DisposableBeanAdapter存入该Map中。

调用它的destroy方法时,会逐个调用Map元素的run方法(实际就是DisposableBeanAdapter.destroy()方法,逻辑同上):

public void destroy() {
    for (Runnable runnable : this.destructionCallbacks.values()) {
	    runnable.run();
	}
	this.destructionCallbacks.clear();
}

至此,createBean方法执行结束。

3.doGetBean的后续操作

对於单例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不符合需要,从而抛出异常。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章