参考资料:
《Spring IoC源码学习:createBean 详解(上)》
前文:
写在开头:本文为个人学习笔记,内容比较随意,夹杂个人理解,如有错误,欢迎指正。
目录
3、applyBeanPostProcessorsBeforeInstantiation
3、determineConstructorsFromBeanPostProcessors
3、determineHighestPriorityCandidate
一、createBean
1、createBean
(1)resolveBeanClass通过mbd与beanName解析得到类的全路径,验证及准备覆盖的方法(对override属性进行标记及验证)。
(2)实例化前,给InstantiationAwareBeanPostProcessor一个机会返回代理对象来替代真正的bean实例,达到“短路”效果,如果返回的bean不为空,则会跳过Spring默认的实例化过程,直接使用返回的bean。
(3)调用doCreateBean创建Bean实例(真正创建Bean的方法)并返回。
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
// 1.解析beanName对应的Bean的类型,例如:com.joonwhee.open.demo.service.impl.UserServiceImpl
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
// 如果resolvedClass存在,并且mdb的beanClass类型不是Class,并且mdb的beanClass不为空(则代表beanClass存的是Class的name),
// 则使用mdb深拷贝一个新的RootBeanDefinition副本,并且将解析的Class赋值给拷贝的RootBeanDefinition副本的beanClass属性,
// 该拷贝副本取代mdb用于后续的操作
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
// 2.验证及准备覆盖的方法(对override属性进行标记及验证)
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 3.实例化前的处理,给InstantiationAwareBeanPostProcessor一个机会返回代理对象来替代真正的bean实例,达到“短路”效果
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
// 4.如果bean不为空,则会跳过Spring默认的实例化过程,直接使用返回的bean
if (bean != null) {
return bean;
}
} catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
// 5.创建Bean实例(真正创建Bean的方法)
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
// 6.返回创建的Bean实例
return beanInstance;
}
2、resolveBeforeInstantiation
(1)若mbd不是合成的,并且BeanFactory中存在InstantiationAwareBeanPostProcessor,则继续往下。
(2)解析beanName对应的Bean实例的类型,若不为空则调用applyBeanPostProcessorsBeforeInstantiation,在实例化前调用后置处理器处理InstantiationAwareBeanPostProcessor,如果返回的bean不为空,则直接调用BeanPostProcessor实现类的postProcessAfterInitialization方法。(因为这里bean不为空会跳过后续的Spring默认的实例化过程,所以这里需要单独为其执行后置处理器)
(3)如果bean不为空,则将beforeInstantiationResolved赋值为true,代表在实例化之前已经解析。
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
// 1.mbd不是合成的,并且BeanFactory中存在InstantiationAwareBeanPostProcessor
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 2.解析beanName对应的Bean实例的类型
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 3.实例化前的后置处理器应用(处理InstantiationAwareBeanPostProcessor)
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
// 4.如果返回的bean不为空,会跳过Spring默认的实例化过程,
// 所以只能在这里调用BeanPostProcessor实现类的postProcessAfterInitialization方法
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
// 5.如果bean不为空,则将beforeInstantiationResolved赋值为true,代表在实例化之前已经解析
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
3、applyBeanPostProcessorsBeforeInstantiation
(1)遍历当前BeanFactory中的BeanPostProcessor,如果是InstantiationAwareBeanPostProcessor类型,则执行postProcessBeforeInstantiation方法,
可直接得到一个构造完成的bean实例,从而不会继续执行创建Bean实例的“正规的流程”,达到“短路”的效果。
(2)如果result不为空,也就是有后置处理器返回了bean实例对象,则直接返回。
注意:postProcessBeforeInstantiation(注意名字,BeforeInstantiation不是BeforeInitialization),该方法是最先执行的方法,它在目标对象实例化之前调用,该方法的返回值类型是Object,我们可以返回任何类型的值。由于这个时候目标对象还未实例化,所以这个返回值可以用来代替原本该生成的目标对象的实例(比如代理对象)。如果该方法的返回值代替原本该生成的目标对象,后续只有postProcessAfterInitialization方法会调用,其它方法不再调用;否则按照正常的流程走。
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
// 1.遍历当前BeanFactory中的BeanPostProcessor
for (BeanPostProcessor bp : getBeanPostProcessors()) {
// 2.应用InstantiationAwareBeanPostProcessor后置处理器,允许postProcessBeforeInstantiation方法返回bean对象的代理
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 3.执行postProcessBeforeInstantiation方法,在Bean实例化前操作,
// 该方法可以返回一个构造完成的Bean实例,从而不会继续执行创建Bean实例的“正规的流程”,达到“短路”的效果。
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
// 4.如果result不为空,也就是有后置处理器返回了bean实例对象,则会跳过Spring默认的实例化过程
return result;
}
}
}
return null;
}
二、doCreateBean
1、doCreateBean
(1)判断是否为FactoryBean,如是则需要先移除未完成的FactoryBean实例的缓存
(2)根据根据beanName、mbd、args,使用对应的策略(createBeanInstance)创建Bean实例,并返回包装类BeanWrapper。拿到创建好的Bean实例,获取其类型。
(3)调用applyMergedBeanDefinitionPostProcessors方法执行后置处理器MergedBeanDefinitionPostProcessor。(此方法允许修改MergedBeanDefinition,Autowired注解正是通过此方法实现注入类型的预解析)。
(4)判断是否需要提早曝光实例,判断条件为单例 && 允许循环依赖 && 当前bean正在创建中,如满足要求,则调用addSingletonFactory方法,提前曝光beanName的ObjectFactory,用于解决循环引用。(其内部重写了getObject方法,通过getEarlyBeanReference调用应用后置处理器SmartInstantiationAwareBeanPostProcessor,允许返回指定bean的早期引用,若没有则直接返回bean)。
(5)对bean进行属性填充;其中,可能存在依赖于其他bean的属性,则会递归初始化依赖的bean实例。
(6)如果允许提前曝光实例,则调用getSingleton获取缓存对象,进行循环依赖检查。
(7)注册用于销毁的bean,并完成bean的创建和返回。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// Instantiate the bean.
// 1.新建Bean包装类
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 2.如果是FactoryBean,则需要先移除未完成的FactoryBean实例的缓存
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 3.根据beanName、mbd、args,使用对应的策略创建Bean实例,并返回包装类BeanWrapper
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 4.拿到创建好的Bean实例
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
// 5.拿到Bean实例的类型
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 6.应用后置处理器MergedBeanDefinitionPostProcessor,允许修改MergedBeanDefinition,
// Autowired注解正是通过此方法实现注入类型的预解析
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.
// 7.判断是否需要提早曝光实例:单例 && 允许循环依赖 && 当前bean正在创建中
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 8.提前曝光beanName的ObjectFactory,用于解决循环引用
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
// 8.1 应用后置处理器SmartInstantiationAwareBeanPostProcessor,允许返回指定bean的早期引用,若没有则直接返回bean
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// Initialize the bean instance. 初始化bean实例。
Object exposedObject = bean;
try {
// 9.对bean进行属性填充;其中,可能存在依赖于其他bean的属性,则会递归初始化依赖的bean实例
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
// 10.对bean进行初始化
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) {
// 11.如果允许提前曝光实例,则进行循环依赖检查
Object earlySingletonReference = getSingleton(beanName, false);
// 11.1 earlySingletonReference只有在当前解析的bean存在循环依赖的情况下才会不为空
if (earlySingletonReference != null) {
if (exposedObject == bean) {
// 11.2 如果exposedObject没有在initializeBean方法中被增强,则不影响之前的循环引用
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
// 11.3 如果exposedObject在initializeBean方法中被增强 && 不允许在循环引用的情况下使用注入原始bean实例
// && 当前bean有被其他bean依赖
// 11.4 拿到依赖当前bean的所有bean的beanName数组
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
// 11.5 尝试移除这些bean的实例,因为这些bean依赖的bean已经被增强了,他们依赖的bean相当于脏数据
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
// 11.6 移除失败的添加到 actualDependentBeans
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
// 11.7 如果存在移除失败的,则抛出异常,因为存在bean依赖了“脏数据”
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.");
}
}
}
}
// Register bean as disposable.
try {
// 12.注册用于销毁的bean,执行销毁操作的有三种:自定义destroy方法、DisposableBean接口、DestructionAwareBeanPostProcessor
registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
// 13.完成创建并返回
return exposedObject;
}
2、createBeanInstance
(1)解析bean的类型信息,如果beanClass不为空 && beanClass不是公开类(不是public修饰) && 该bean不允许访问非公共构造函数和方法,则抛异常。
(2)如果存在工厂方法则使用工厂方法实例化bean对象,如不是,通过resolvedConstructorOrFactoryMethod缓存判断构造函数或工厂方法是否已经解析过,根据constructorArgumentsResolved判断是否需要自动注入
(3)如果已经解析过,则使用resolvedConstructorOrFactoryMethod缓存里解析好的构造函数方法,否则使用默认的构造函数进行bean的实例化。
(4)使用determineConstructorsFromBeanPostProcessors方法,通过SmartInstantiationAwareBeanPostProcessor拿到bean的候选构造函数,如果ctors不为空 || mbd的注入方式为AUTOWIRE_CONSTRUCTOR || mdb定义了构造函数的参数值 || args不为空,则执行构造函数自动注入。否则使用默认的构造函数进行bean的实例化。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// Make sure bean class is actually resolved at this point.
// 解析bean的类型信息
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
// beanClass不为空 && beanClass不是公开类(不是public修饰) && 该bean不允许访问非公共构造函数和方法,则抛异常
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
// 1.如果存在工厂方法则使用工厂方法实例化bean对象
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
// resolved: 构造函数或工厂方法是否已经解析过
boolean resolved = false;
// autowireNecessary: 是否需要自动注入(即是否需要解析构造函数参数)
boolean autowireNecessary = false;
if (args == null) {
// 2.加锁
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
// 2.1 如果resolvedConstructorOrFactoryMethod缓存不为空,则将resolved标记为已解析
resolved = true;
// 2.2 根据constructorArgumentsResolved判断是否需要自动注入
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
// 3.如果已经解析过,则使用resolvedConstructorOrFactoryMethod缓存里解析好的构造函数方法
if (autowireNecessary) {
// 3.1 需要自动注入,则执行构造函数自动注入
return autowireConstructor(beanName, mbd, null, null);
} else {
// 3.2 否则使用默认的构造函数进行bean的实例化
return instantiateBean(beanName, mbd);
}
}
// Need to determine the constructor...
// 4.应用后置处理器SmartInstantiationAwareBeanPostProcessor,拿到bean的候选构造函数
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 5.如果ctors不为空 || mbd的注入方式为AUTOWIRE_CONSTRUCTOR || mdb定义了构造函数的参数值 || args不为空,则执行构造函数自动注入
return autowireConstructor(beanName, mbd, ctors, args);
}
// No special handling: simply use no-arg constructor.
// 6.没有特殊处理,则使用默认的构造函数进行bean的实例化
return instantiateBean(beanName, mbd);
}
3、determineConstructorsFromBeanPostProcessors
遍历所有的BeanPostProcessor,判断是否为SmartInstantiationAwareBeanPostProcessor类型,如是的话则调用SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors方法,该方法可以返回要用于beanClass的候选构造函数,例如:使用@Autowire注解修饰构造函数,则该构造函数在这边会被AutowiredAnnotationBeanPostProcessor找到
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(Class<?> beanClass, String beanName)
throws BeansException {
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
// 1.遍历所有的BeanPostProcessor
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
// 2.调用SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors方法,
// 该方法可以返回要用于beanClass的候选构造函数
// 例如:使用@Autowire注解修饰构造函数,则该构造函数在这边会被AutowiredAnnotationBeanPostProcessor找到
Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
// 3.如果ctors不为空,则不再继续执行其他的SmartInstantiationAwareBeanPostProcessor
return ctors;
}
}
}
}
return null;
}
三、autowireConstructor
autowireConstructor为构造函数自动装配。
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, Constructor<?>[] ctors, Object[] explicitArgs) {
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,
Constructor<?>[] chosenCtors, final Object[] explicitArgs) {
1、获取用于实例化的构造函数参数
2、从配置文件中获取构造函数
2.1、检查是否需要自动装配
2.2、获取构造函数参数个数
2.3、确认构造函数的候选者
2.4、对给定的构造函数排序
2.5、遍历所有构造函数候选者,找出符合条件的构造函数
2.6、根据权重确认构造函数
2.7、确认构造函数
}
1、获取用于实例化的构造函数参数
(1)判断是否已解析过构造函数(根据入参explicitArgs是否为空判断),不为空则直接使用参数中传递过来的值。
(2)若为空,则需要从缓存中获取。
(2.1)先从mbd.resolvedConstructorOrFactoryMethod方法获取用于实例化的构造函数(constructorToUse )。
(2.2)如果constructorToUse不为空 ,且mbd标记了构造函数参数已解析,则尝试从缓存中获取已解析的构造函数参数(argsToUse = mbd.resolvedConstructorArguments;)。
(2.3)如果获取到的参数依然为空,则从缓存中获取准备用于解析的构造函数参数(根据之前的判断constructorArgumentsResolved为true,那么resolvedConstructorArguments和preparedConstructorArguments必然存在一个缓存了构造函数的参数)。
// 定义bean包装类
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
// 最终用于实例化的构造函数
Constructor<?> constructorToUse = null;
// 最终用于实例化的参数Holder
ArgumentsHolder argsHolderToUse = null;
// 最终用于实例化的构造函数参数
Object[] argsToUse = null;
// 1.解析出要用于实例化的构造函数参数
if (explicitArgs != null) {
// 1.1 如果explicitArgs不为空,则构造函数的参数直接使用explicitArgs
// 通过getBean方法调用时,显示指定了参数,则explicitArgs就不为null
argsToUse = explicitArgs;
}
else {
// 1.2 尝试从缓存中获取已经解析过的构造函数参数
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
// 1.2.1 拿到缓存中已解析的构造函数或工厂方法
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
// 1.2.2 如果constructorToUse不为空 && mbd标记了构造函数参数已解析
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached constructor...
// 1.2.3 从缓存中获取已解析的构造函数参数
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
// 1.2.4 如果resolvedConstructorArguments为空,则从缓存中获取准备用于解析的构造函数参数,
// constructorArgumentsResolved为true时,resolvedConstructorArguments和
// preparedConstructorArguments必然有一个缓存了构造函数的参数
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
if (argsToResolve != null) {
// 1.2.5 如果argsToResolve不为空,则对构造函数参数进行解析,
// 如给定方法的构造函数 A(int,int)则通过此方法后就会把配置中的("1","1")转换为(1,1)
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
}
}
2、从配置文件中获取构造函数
如果构造函数没有被缓存,则通过配置文件获取
2.1、检查是否需要自动装配
检查是否需要自动装配,判断条件chosenCtors不为空或autowireMode为AUTOWIRE_CONSTRUCTOR。
// 检查是否需要自动装配:chosenCtors不为空 || autowireMode为AUTOWIRE_CONSTRUCTOR
// 例子:当chosenCtors不为空时,代表有构造函数通过@Autowire修饰,因此需要自动装配
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
2.2、获取构造函数参数个数
(1)若explicitArgs不为空,则使用explicitArgs的length作为minNrOfArgs的值。
(2)否则通过mbd获取构造函数的参数值(分为两种indexedArgumentValues:带index的参数值;genericArgumentValues:通用的参数值),调用resolveConstructorArguments方法获取。
// 构造函数参数个数
int minNrOfArgs;
if (explicitArgs != null) {
// explicitArgs不为空,则使用explicitArgs的length作为minNrOfArgs的值
minNrOfArgs = explicitArgs.length;
}
else {
// 获得mbd的构造函数的参数值(indexedArgumentValues:带index的参数值;genericArgumentValues:通用的参数值)
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
// 创建ConstructorArgumentValues对象resolvedValues,用于承载解析后的构造函数参数的值
resolvedValues = new ConstructorArgumentValues();
// 解析mbd的构造函数的参数,并返回参数个数
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
// 注:这边解析mbd中的构造函数参数值,主要是处理我们通过xml方式定义的构造函数注入的参数,
// 但是如果我们是通过@Autowire注解直接修饰构造函数,则mbd是没有这些参数值的
}
2.3、确认构造函数的候选者
(1)如果入参chosenCtors不为空,则将chosenCtors的构造函数作为候选者。
(2)如果入参chosenCtors为空,则先通过getBeanClass获取到beanClass,然后通过判断mbd是否允许访问非公共构造函数和方法,选择是获取所有声明的构造函数还是公共构造函数。
// 确认构造函数的候选者
// Take specified constructors, if any.
// 如果入参chosenCtors不为空,则将chosenCtors的构造函数作为候选者
Constructor<?>[] candidates = chosenCtors;
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
try {
// 如果入参chosenCtors为空,则获取beanClass的构造函数
// (mbd是否允许访问非公共构造函数和方法 ? 所有声明的构造函数:公共构造函数)
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);
}
}
2.4、对给定的构造函数排序
// 对给定的构造函数排序:先按方法修饰符排序:public排非public前面,再按构造函数参数个数排序:参数多的排前面
AutowireUtils.sortConstructors(candidates);
// 最小匹配权重,权重越小,越接近我们要找的目标构造函数
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;
2.5、遍历所有构造函数候选者,找出符合条件的构造函数
// 遍历所有构造函数候选者,找出符合条件的构造函数
for (Constructor<?> candidate : candidates) {
1. 拿到当前遍历的构造函数的参数类型数组
2. 判断当前构造函数是否满足基本确认条件
3. 判断是否存在参数
}
2.5.1、拿到当前遍历的构造函数的参数类型数组
// 拿到当前遍历的构造函数的参数类型数组
Class<?>[] paramTypes = candidate.getParameterTypes();
2.5.2、判断当前构造函数是否满足基本确认条件
(1)如果已经找到满足的构造函数 && 目标构造函数需要的参数个数大于当前遍历的构造函数的参数个数则终止,因为遍历的构造函数已经排过序,后面不会有更合适的候选者了。
(2)如果当前遍历到的构造函数的参数个数小于我们所需的参数个数,则直接跳过该构造函数。
if (constructorToUse != null && argsToUse.length > paramTypes.length) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
// 如果已经找到满足的构造函数 && 目标构造函数需要的参数个数大于当前遍历的构造函数的参数个数则终止,
// 因为遍历的构造函数已经排过序,后面不会有更合适的候选者了
break;
}
if (paramTypes.length < minNrOfArgs) {
// 如果当前遍历到的构造函数的参数个数小于我们所需的参数个数,则直接跳过该构造函数
continue;
}
2.5.3、判断是否存在参数
(1)参数不为空,则通过解析使用ConstructorProperties注解的构造函数参数,获取当前遍历的构造函数的参数名称。
(1.1)先获取参数名称解析器,若参数名称解析器不为空,再使用参数名称解析器获取当前遍历的构造函数的参数名称。
(1.2)最后通过参数类型和参数名解析构造函数或工厂方法所需的参数(如果参数是其他bean,则会解析依赖的bean)
(2)参数为空,判断参数个数与explicitArgs是否相等,不相等则跳出。使用显式给出的参数构造ArgumentsHolder返回参数。
ArgumentsHolder argsHolder;
if (resolvedValues != null) {
// 存在参数则根据参数值来匹配参数类型
try {
// resolvedValues不为空,
// 获取当前遍历的构造函数的参数名称
// 解析使用ConstructorProperties注解的构造函数参数
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
if (paramNames == null) {
// 获取参数名称解析器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
// 使用参数名称解析器获取当前遍历的构造函数的参数名称
paramNames = pnd.getParameterNames(candidate);
}
}
// 创建一个参数数组以调用构造函数或工厂方法,
// 主要是通过参数类型和参数名解析构造函数或工厂方法所需的参数(如果参数是其他bean,则会解析依赖的bean)
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring);
}
catch (UnsatisfiedDependencyException ex) {
// 参数匹配失败,则抛出异常
if (this.beanFactory.logger.isTraceEnabled()) {
this.beanFactory.logger.trace(
"Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next constructor.
if (causes == null) {
causes = new LinkedList<UnsatisfiedDependencyException>();
}
causes.add(ex);
continue;
}
}
else {
// resolvedValues为空,则explicitArgs不为空,即给出了显式参数
// Explicit arguments given -> arguments length must match exactly.
// 如果当前遍历的构造函数参数个数与explicitArgs长度不相同,则跳过该构造函数
if (paramTypes.length != explicitArgs.length) {
continue;
}
// 使用显式给出的参数构造ArgumentsHolder
argsHolder = new ArgumentsHolder(explicitArgs);
}
2.6、根据权重确认构造函数
根据mbd的解析构造函数模式(true: 宽松模式(默认),false:严格模式),将argsHolder的参数和paramTypes进行比较,计算paramTypes的类型差异权重值。
(1)类型差异权重值越小,则说明构造函数越匹配,则选择此构造函数。
(2)如果存在两个候选者的权重值相同,并且是当前遍历过权重值最小的。
// 根据mbd的解析构造函数模式(true: 宽松模式(默认),false:严格模式),
// 将argsHolder的参数和paramTypes进行比较,计算paramTypes的类型差异权重值
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清空,允许之前存在权重值相同的候选者
ambiguousConstructors = null;
}
// 如果存在两个候选者的权重值相同,并且是当前遍历过权重值最小的
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
// 将这两个候选者都添加到ambiguousConstructors
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<Constructor<?>>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}
2.7、确认构造函数
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 " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
}
else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
// 如果找到了匹配的构造函数,但是存在多个(ambiguousConstructors不为空) && 解析构造函数的模式为严格模式,则抛出异常
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous constructor matches found in bean '" + beanName + "' " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousConstructors);
}
if (explicitArgs == null) {
// 将解析的构造函数和参数放到缓存
argsHolderToUse.storeCache(mbd, constructorToUse);
}
3、 实例化Bean
try {
Object beanInstance;
// 根据实例化策略以及得到的构造函数及构造函数参数实例化bean
if (System.getSecurityManager() != null) {
final Constructor<?> ctorToUse = constructorToUse;
final Object[] argumentsToUse = argsToUse;
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
return beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, beanFactory, ctorToUse, argumentsToUse);
}
}, beanFactory.getAccessControlContext());
}
else {
beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
}
// 将构造的实例加入BeanWrapper中,并返回
bw.setBeanInstance(beanInstance);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean instantiation via constructor failed", ex);
}
四、resolveConstructorArguments
1、resolveConstructorArguments
解析构造函数的参数,将解析后的参数置入resolvedValues中。分别对带index的参数(indexedArgumentValues)和不带index的参数(genericArgumentValues)进行处理。
private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,
ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {
// 1.构建bean定义值解析器
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
TypeConverter converter = (customConverter != null ? customConverter : bw);
BeanDefinitionValueResolver valueResolver =
new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
// 2.minNrOfArgs初始化为indexedArgumentValues和genericArgumentValues的的参数个数总和
int minNrOfArgs = cargs.getArgumentCount();
// 3.遍历解析带index的参数值
for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : cargs.getIndexedArgumentValues().entrySet()) {
int index = entry.getKey();
if (index < 0) {
// index从0开始,不允许小于0
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Invalid constructor argument index: " + index);
}
// 3.1 如果index大于minNrOfArgs,则修改minNrOfArgs
if (index > minNrOfArgs) {
// index是从0开始,并且是有序递增的,所以当有参数的index=5时,代表该方法至少有6个参数
minNrOfArgs = index + 1;
}
ConstructorArgumentValues.ValueHolder valueHolder = entry.getValue();
// 3.2 解析参数值
if (valueHolder.isConverted()) {
// 3.2.1 如果参数值已经转换过,则直接将index和valueHolder添加到resolvedValues的indexedArgumentValues属性
resolvedValues.addIndexedArgumentValue(index, valueHolder);
} else {
// 3.2.2 如果值还未转换过,则先进行转换
Object resolvedValue =
valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
// 3.2.3 使用转换后的resolvedValue构建新的ValueHolder
ConstructorArgumentValues.ValueHolder resolvedValueHolder =
new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
// 3.2.4 将转换前的valueHolder保存到新的ValueHolder的source属性
resolvedValueHolder.setSource(valueHolder);
// 3.2.5 将index和新的ValueHolder添加到resolvedValues的indexedArgumentValues属性
resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder);
}
}
// 4.遍历解析通用参数值(不带index)
for (ConstructorArgumentValues.ValueHolder valueHolder : cargs.getGenericArgumentValues()) {
if (valueHolder.isConverted()) {
// 4.1 如果参数值已经转换过,则直接将valueHolder添加到resolvedValues的genericArgumentValues属性
resolvedValues.addGenericArgumentValue(valueHolder);
} else {
// 4.2 如果值还未转换过,则先进行转换
Object resolvedValue =
valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
// 4.3 使用转换后的resolvedValue构建新的ValueHolder
ConstructorArgumentValues.ValueHolder resolvedValueHolder =
new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
// 4.4 将转换前的valueHolder保存到新的ValueHolder的source属性
resolvedValueHolder.setSource(valueHolder);
// 4.5 将新的ValueHolder添加到resolvedValues的genericArgumentValues属性
resolvedValues.addGenericArgumentValue(resolvedValueHolder);
}
}
// 5.返回构造函数参数的个数
return minNrOfArgs;
}
2、createArgumentArray
private ArgumentsHolder createArgumentArray(
String beanName, RootBeanDefinition mbd, ConstructorArgumentValues resolvedValues,
BeanWrapper bw, Class<?>[] paramTypes, String[] paramNames, Object methodOrCtor,
boolean autowiring) throws UnsatisfiedDependencyException {
1. 数据准备
2. 遍历参数类型数组,解析参数并赋值给args
3. 如果依赖了其他的bean,则注册依赖关系
}
2.1、数据准备
获取类型转换器,新建一个ArgumentsHolder来存放匹配到的参数。
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
// 获取类型转换器
TypeConverter converter = (customConverter != null ? customConverter : bw);
// 新建一个ArgumentsHolder来存放匹配到的参数
ArgumentsHolder args = new ArgumentsHolder(paramTypes.length);
Set<ConstructorArgumentValues.ValueHolder> usedValueHolders =
new HashSet<ConstructorArgumentValues.ValueHolder>(paramTypes.length);
Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);
2.2、遍历参数类型数组,解析参数并赋值给args
// 遍历参数类型数组
for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++){}
(2.2.1)拿到当前遍历的参数类型、参数名,查找当前遍历的参数,是否在mdb对应的bean的构造函数参数中存在index、类型和名称匹配的。如果找不到找不到直接匹配并且不应该自动装配,则尝试下一个通用的无类型参数值作为降级方法:它可以在类型转换后匹配(例如,String - > int)。
// 拿到当前遍历的参数类型
Class<?> paramType = paramTypes[paramIndex];
// 拿到当前遍历的参数名
String paramName = (paramNames != null ? paramNames[paramIndex] : "");
// Try to find matching constructor argument value, either indexed or generic.
// 查找当前遍历的参数,是否在mdb对应的bean的构造函数参数中存在index、类型和名称匹配的
ConstructorArgumentValues.ValueHolder valueHolder =
resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders);
// 如果我们找不到直接匹配并且不应该自动装配,那么让我们尝试下一个通用的无类型参数值作为降级方法:它可以在类型转换后匹配(例如,String - > int)。
if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) {
valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders);
}
(2.2.2)valueHolder是否为空
(1) valueHolder不为空,存在匹配的参数。
(1.1) 将valueHolder添加到usedValueHolders,并获取转换后的属性值。
(1.2) 如果valueHolder已经转换过,则直接获取转换后的值,将convertedValue作为args在paramIndex位置的预备参数。
(1.3) 如果valueHolder还未转换过,拿到原始的ValueHolder,将方法(此处为构造函数)和参数索引封装成MethodParameter(MethodParameter是封装方法和参数索引的工具类),然后将原始值转换为paramType类型的值(如果类型无法转,抛出TypeMismatchException)
并将args标记为需要解析args标记为需要解析,最后将convertedValue作为args在paramIndex位置的预备参数。
(1.4)将convertedValue作为args在paramIndex位置的参数,将originalValue作为args在paramIndex位置的原始参数。
// valueHolder不为空,存在匹配的参数
// We found a potential match - let's give it a try.
// Do not consider the same value definition multiple times!
// 将valueHolder添加到usedValueHolders
usedValueHolders.add(valueHolder);
// 原始属性值
Object originalValue = valueHolder.getValue();
// 转换后的属性值
Object convertedValue;
if (valueHolder.isConverted()) {
// 如果valueHolder已经转换过
// 则直接获取转换后的值
convertedValue = valueHolder.getConvertedValue();
// 将convertedValue作为args在paramIndex位置的预备参数
args.preparedArguments[paramIndex] = convertedValue;
} else {
// 如果valueHolder还未转换过
// 拿到原始的ValueHolder
ConstructorArgumentValues.ValueHolder sourceHolder =
(ConstructorArgumentValues.ValueHolder) valueHolder.getSource();
// 拿到原始参数值
Object sourceValue = sourceHolder.getValue();
// 将方法(此处为构造函数)和参数索引封装成MethodParameter(MethodParameter是封装方法和参数索引的工具类)
MethodParameter methodParam = MethodParameter.forMethodOrConstructor(methodOrCtor, paramIndex);
try {
// 将原始值转换为paramType类型的值(如果类型无法转,抛出TypeMismatchException)
convertedValue = converter.convertIfNecessary(originalValue, paramType, methodParam);
// TODO re-enable once race condition has been found (SPR-7423)
/*
if (originalValue == sourceValue || sourceValue instanceof TypedStringValue) {
// Either a converted value or still the original one: store converted value.
sourceHolder.setConvertedValue(convertedValue);
args.preparedArguments[paramIndex] = convertedValue;
}
else {
*/
// args标记为需要解析
args.resolveNecessary = true;
// 将convertedValue作为args在paramIndex位置的预备参数
args.preparedArguments[paramIndex] = sourceValue;
// }
} catch (TypeMismatchException ex) {
// 如果类型转换失败,则抛出异常
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
"Could not convert argument value of type [" +
ObjectUtils.nullSafeClassName(valueHolder.getValue()) +
"] to required type [" + paramType.getName() + "]: " + ex.getMessage());
}
}
// 将convertedValue作为args在paramIndex位置的参数
args.arguments[paramIndex] = convertedValue;
// 将originalValue作为args在paramIndex位置的原始参数
args.rawArguments[paramIndex] = originalValue
(2)valueHolder为空,不存在匹配的参数
(2.1) 将方法(此处为构造函数)和参数索引封装成MethodParameter,如果找不到明确的匹配,并且不是自动装配,则抛出异常。
(2.2) 如果是自动装配,则调用用于解析自动装配参数的方法,返回的结果为依赖的bean实例对象(例如:@Autowire修饰构造函数,自动注入构造函数中的参数bean就是在这边处理)。
(2.3) 将通过自动装配解析出来的参数赋值给args。
// valueHolder为空,不存在匹配的参数
// 将方法(此处为构造函数)和参数索引封装成MethodParameter
MethodParameter methodParam = MethodParameter.forMethodOrConstructor(methodOrCtor, paramIndex);
// No explicit match found: we're either supposed to autowire or
// have to fail creating an argument array for the given constructor.
// 找不到明确的匹配,并且不是自动装配,则抛出异常
if (!autowiring) {
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
"Ambiguous argument values for parameter of type [" + paramType.getName() +
"] - did you specify the correct bean references as arguments?");
}
try {
// 如果是自动装配,则调用用于解析自动装配参数的方法,返回的结果为依赖的bean实例对象
// 例如:@Autowire修饰构造函数,自动注入构造函数中的参数bean就是在这边处理
Object autowiredArgument =
resolveAutowiredArgument(methodParam, beanName, autowiredBeanNames, converter);
// 将通过自动装配解析出来的参数赋值给args
args.rawArguments[paramIndex] = autowiredArgument;
args.arguments[paramIndex] = autowiredArgument;
args.preparedArguments[paramIndex] = new AutowiredArgumentMarker();
args.resolveNecessary = true;
} catch (BeansException ex) {
// 如果自动装配解析失败,则会抛出异常
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), ex);
}
2.3、如果依赖了其他的bean,则注册依赖关系
// 如果依赖了其他的bean,则注册依赖关系
for (String autowiredBeanName : autowiredBeanNames) {
this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
if (this.beanFactory.logger.isDebugEnabled()) {
this.beanFactory.logger.debug("Autowiring by type from bean name '" + beanName +
"' via " + (methodOrCtor instanceof Constructor ? "constructor" : "factory method") +
" to bean named '" + autowiredBeanName + "'");
}
}
3、resolveAutowiredArgument
针对自动装配,解析自动装配参数,返回的结果为依赖的 bean 实例对象。
protected Object resolveAutowiredArgument(
MethodParameter param, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) {
// 1.如果参数类型为InjectionPoint
if (InjectionPoint.class.isAssignableFrom(param.getParameterType())) {
// 1.1 拿到当前的InjectionPoint(存储了当前正在解析依赖的方法参数信息,DependencyDescriptor)
InjectionPoint injectionPoint = currentInjectionPoint.get();
if (injectionPoint == null) {
// 1.2 当前injectionPoint为空,则抛出异常:目前没有可用的InjectionPoint
throw new IllegalStateException("No current InjectionPoint available for " + param);
}
// 1.3 返回当前的InjectionPoint
return injectionPoint;
}
// 2.解析指定依赖,DependencyDescriptor:将MethodParameter的方法参数索引信息封装成DependencyDescriptor
return this.beanFactory.resolveDependency(
new DependencyDescriptor(param, true), beanName, autowiredBeanNames, typeConverter);
}
4、resolveDependency
解析指定依赖。
@Override
public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName,
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (javaUtilOptionalClass == descriptor.getDependencyType()) {
// 1.javaUtilOptionalClass类注入的特殊处理
return new OptionalDependencyFactory().createOptionalDependency(descriptor, requestingBeanName);
} else if (ObjectFactory.class == descriptor.getDependencyType() ||
// 2.ObjectFactory类注入的特殊处理
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
} else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
// 3.javaxInjectProviderClass类注入的特殊处理
return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);
} else {
// 4.通用类注入的处理
// 4.1 如有必要,请获取延迟解析代理
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
// 4.2 解析依赖关系,返回的result为创建好的依赖对象的bean实例
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
五、doResolveDependency
1、doResolveDependency
1.设置当前的descriptor(存储了方法参数等信息)为当前注入点。
2.如果是ShortcutDependencyDescriptor,则直接通过getBean方法获取Bean实例,并返回;否则返回null。
3.拿到descriptor包装的方法的参数类型(通过参数索引定位到具体的参数)。
4.确定给定的依赖项是否声明Value注解,如不为空则进行解析并将解析到的值转换成所需的类型并返回。
// 1.设置当前的descriptor(存储了方法参数等信息)为当前注入点
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
// 2.如果是ShortcutDependencyDescriptor,则直接通过getBean方法获取Bean实例,并返回;否则返回null
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
// 3.拿到descriptor包装的方法的参数类型(通过参数索引定位到具体的参数)
Class<?> type = descriptor.getDependencyType();
// 4.用于支持spring中新增的注解@Value(确定给定的依赖项是否声明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());
// 4.1 如果使用了@Value注解,则将解析到的值转换成所需的类型并返回
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
5.解析MultipleBean(下文的MultipleBean都是指类型为:Array、Collection、Map),如果确实是容器类型的属性,则直接返回解析结果。
6.查找与所需类型匹配的Bean实例(matchingBeans,key:beanName;value:匹配的bean实例,或者匹配的bean实例的类型),如果require属性为true,而找到的匹配Bean却为空则抛出异常,如果require属性为false,而找到的匹配Bean却为空,则返回nul。
7. 如果非MultipleBean
7.1 如果有多个候选者,调用determineAutowireCandidate从多个候选者中选出最优的那个,拿到autowiredBeanName对应的value(bean实例或bean实例类型)。
7.2 如果只找到了一个候选者,则直接使用该候选者。
// 5.解析MultipleBean(下文的MultipleBean都是指类型为:Array、Collection、Map)
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
// 5.1 如果确实是容器类型的属性,则直接返回解析结果
return multipleBeans;
}
// 6.查找与所需类型匹配的Bean实例(matchingBeans,key:beanName;value:匹配的bean实例,或者匹配的bean实例的类型)
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
// 6.1 如果require属性为true,而找到的匹配Bean却为空则抛出异常
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
// 6.2 如果require属性为false,而找到的匹配Bean却为空,则返回nul
return null;
}
String autowiredBeanName;
Object instanceCandidate;
if (matchingBeans.size() > 1) {
// 7.非MultipleBean,但是有多个候选者
// 7.1 从多个候选者中选出最优的那个
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(type, matchingBeans);
} else {
// In case of an optional Collection/Map, silently ignore a non-unique case:
// possibly it was meant to be an empty collection of multiple regular beans
// (before 4.3 in particular when we didn't even look for collection beans).
return null;
}
}
// 7.2.拿到autowiredBeanName对应的value(bean实例或bean实例类型)
instanceCandidate = matchingBeans.get(autowiredBeanName);
} else {
// 8.只找到了一个候选者,则直接使用该候选者
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
8. 将依赖的beanName加到autowiredBeanNames中。
9.如果instanceCandidate为Class,则instanceCandidate为bean实例的类型,执行descriptor.resolveCandidate方法,通过getBean方法获取bean实例并返回;如果instanceCandidate不是Class,则instanceCandidate为bean实例,直接返回该实例。
10. 执行结束,将注入点修改成原来的注入点。
if (autowiredBeanNames != null) {
// 9.将依赖的beanName加到autowiredBeanNames中
autowiredBeanNames.add(autowiredBeanName);
}
// 10.如果instanceCandidate为Class,则instanceCandidate为bean实例的类型,执行descriptor.resolveCandidate方法,
// 通过getBean方法获取bean实例并返回;如果instanceCandidate不是Class,则instanceCandidate为bean实例,直接返回该实例
return (instanceCandidate instanceof Class ?
descriptor.resolveCandidate(autowiredBeanName, type, this) : instanceCandidate);
} finally {
// 11.执行结束,将注入点修改成原来的注入点
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
2、findAutowireCandidates
(1)获取给定类型的所有beanName,包括在祖先工厂中定义的beanName
(2)首先从已经解析的依赖关系缓存中寻找是否存在我们想要的类型。
(2.1)autowiringType是否与requiredType相同,或者是requiredType的超类、超接口。
(2.2)如果requiredType匹配,则从缓存中拿到相应的自动装配值(bean实例)。
(2.3)根据给定的所需类型解析给定的自动装配值。
(2.4)将autowiringValue放到结果集中,此时的value为bean实例。
(3)遍历从容器中获取到的类型符合的beanName。
(3.1) 如果不是自引用 && candidate有资格作为依赖注入的候选者。
(3.2)将候选者添加到result中。
(4)如果结果为空 && type不是MultipleBean(Array、Collection、Map),则使用降级匹配。
(4.1) 使用降级匹配(跟正常匹配类似)。
(4.2)如果使用降级匹配结果还是空,则考虑自引用。
(4.3)如果是自引用 && (descriptor不是MultiElementDescriptor || beanName不等于候选者)&& candidate允许依赖注入,则将候选者添加到result中。
protected Map<String, Object> findAutowireCandidates(
String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
// 1.获取给定类型的所有beanName,包括在祖先工厂中定义的beanName
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = new LinkedHashMap<String, Object>(candidateNames.length);
// 2.首先从已经解析的依赖关系缓存中寻找是否存在我们想要的类型
for (Class<?> autowiringType : this.resolvableDependencies.keySet()) {
// 2.1 autowiringType是否与requiredType相同,或者是requiredType的超类、超接口
if (autowiringType.isAssignableFrom(requiredType)) {
// 2.2 如果requiredType匹配,则从缓存中拿到相应的自动装配值(bean实例)
Object autowiringValue = this.resolvableDependencies.get(autowiringType);
// 2.3 根据给定的所需类型解析给定的自动装配值
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
if (requiredType.isInstance(autowiringValue)) {
// 2.4 将autowiringValue放到结果集中,此时的value为bean实例
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
// 3.遍历从容器中获取到的类型符合的beanName
for (String candidate : candidateNames) {
// isAutowireCandidate:判断是否有资格作为依赖注入的候选者
// 3.1 如果不是自引用 && candidate有资格作为依赖注入的候选者
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
// 3.2 将候选者添加到result中
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
// 4.如果结果为空 && type不是MultipleBean(Array、Collection、Map),则使用降级匹配
if (result.isEmpty() && !indicatesMultipleBeans(requiredType)) {
// Consider fallback matches if the first pass failed to find anything...
// 4.1 使用降级匹配(跟正常匹配类似)
DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
for (String candidate : candidateNames) {
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
if (result.isEmpty()) {
// Consider self references as a final pass...
// but in the case of a dependency collection, not the very same bean itself.
// 4.2.如果使用降级匹配结果还是空,则考虑自引用
for (String candidate : candidateNames) {
if (isSelfReference(beanName, candidate) &&
(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
isAutowireCandidate(candidate, fallbackDescriptor)) {
// 4.3 如果是自引用 && (descriptor不是MultiElementDescriptor || beanName不等于候选者)
// && candidate允许依赖注入,则将候选者添加到result中
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
}
}
// 6.返回符合条件的候选者
return result;
}
3、addCandidateEntry
添加候选者。
private void addCandidateEntry(Map<String, Object> candidates, String candidateName,
DependencyDescriptor descriptor, Class<?> requiredType) {
// 1.如果descriptor为MultiElementDescriptor类型 || candidateName已经在singletonObjects缓存中存在
if (descriptor instanceof MultiElementDescriptor || containsSingleton(candidateName)) {
// 2.1 resolveCandidate: 通过candidateName获取对应的bean实例
// 2.2 将beanName -> bean实例 的映射添加到candidates(此时的value为bean实例)
candidates.put(candidateName, descriptor.resolveCandidate(candidateName, requiredType, this));
} else {
// 3.将beanName -> bean实例的类型 的映射添加到candidates(此时的value为bean实例的类型)
candidates.put(candidateName, getType(candidateName));
}
}
六、isAutowireCandidate
1、isAutowireCandidate
判断是否有资格作为依赖注入的候选者。
@Override
public boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
throws NoSuchBeanDefinitionException {
// getAutowireCandidateResolver: 返回BeanFactory的@Autowire解析器,开启注解后的解析器为:ContextAnnotationAutowireCandidateResolver
// 解析beanName对应的bean是否有资格作为候选者
return isAutowireCandidate(beanName, descriptor, getAutowireCandidateResolver());
}
protected boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor, AutowireCandidateResolver resolver)
throws NoSuchBeanDefinitionException {
// 1.解析beanName,去掉FactoryBean的修饰符“&”
String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName);
if (containsBeanDefinition(beanDefinitionName)) {
// 2.beanDefinitionMap缓存中存在beanDefinitionName:通过beanDefinitionName缓存拿到MergedBeanDefinition,
// 将MergedBeanDefinition作为参数,解析beanName是否有资格作为候选者
return isAutowireCandidate(beanName, getMergedLocalBeanDefinition(beanDefinitionName), descriptor, resolver);
} else if (containsSingleton(beanName)) {
// 3.singletonObjects缓存中存在beanName:使用beanName构建RootBeanDefinition作为参数,解析beanName是否有资格作为候选者
return isAutowireCandidate(beanName, new RootBeanDefinition(getType(beanName)), descriptor, resolver);
}
// 4.在beanDefinitionMap缓存和singletonObjects缓存中都不存在,则在parentBeanFactory中递归解析beanName是否有资格作为候选者
BeanFactory parent = getParentBeanFactory();
if (parent instanceof DefaultListableBeanFactory) {
// No bean definition found in this factory -> delegate to parent.
return ((DefaultListableBeanFactory) parent).isAutowireCandidate(beanName, descriptor, resolver);
} else if (parent instanceof ConfigurableListableBeanFactory) {
// If no DefaultListableBeanFactory, can't pass the resolver along.
return ((ConfigurableListableBeanFactory) parent).isAutowireCandidate(beanName, descriptor);
} else {
return true;
}
}
2、isAutowireCandidate
将MergedBeanDefinition作为参数,解析beanName是否有资格作为候选者。
protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd,
DependencyDescriptor descriptor, AutowireCandidateResolver resolver) {
// 1.解析beanName,去掉FactoryBean的修饰符“&”
String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName);
// 2.解析mbd的beanClass
resolveBeanClass(mbd, beanDefinitionName);
if (mbd.isFactoryMethodUnique) {
boolean resolve;
synchronized (mbd.constructorArgumentLock) {
resolve = (mbd.resolvedConstructorOrFactoryMethod == null);
}
if (resolve) {
// 3.如果缓存中已经存在解析的构造函数或工厂方法,则解析mbd中的工厂方法,并替换掉缓存中的方法
new ConstructorResolver(this).resolveFactoryMethodIfPossible(mbd);
}
}
// 4.使用resolver解析器解析mbd是否有资格作为依赖注入的候选者
return resolver.isAutowireCandidate(
new BeanDefinitionHolder(mbd, beanName, getAliases(beanDefinitionName)), descriptor);
}
3、isAutowireCandidate
@Override
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
// 1.调用父类方法判断此bean是否可以自动注入到其他bean
boolean match = super.isAutowireCandidate(bdHolder, descriptor);
if (match && descriptor != null) {
// 2.@Qualifiers注解检查
match = checkQualifiers(bdHolder, descriptor.getAnnotations());
if (match) {
MethodParameter methodParam = descriptor.getMethodParameter();
if (methodParam != null) {
Method method = methodParam.getMethod();
if (method == null || void.class == method.getReturnType()) {
match = checkQualifiers(bdHolder, methodParam.getMethodAnnotations());
}
}
}
}
return match;
}
// GenericTypeAwareAutowireCandidateResolver.java
@Override
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
if (!super.isAutowireCandidate(bdHolder, descriptor)) {
// If explicitly false, do not proceed with any other checks...
// 1.如果父类返回false,则直接返回false
return false;
}
// 2.descriptor为空 || bdHolder的类型与descriptor的类型匹配,则返回true
return (descriptor == null || checkGenericTypeMatch(bdHolder, descriptor));
}
// SimpleAutowireCandidateResolver.java
@Override
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
// 获取此bean是否可以自动注入到其他bean(autowireCandidate属性),默认为true,一般不修改,因此这边返回true
return bdHolder.getBeanDefinition().isAutowireCandidate();
}
七、determineAutowireCandidate
1、determineAutowireCandidate
从多个候选者中选出最优的那个。
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
Class<?> requiredType = descriptor.getDependencyType();
// 1.根据@Primary注解来选择最优解
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
if (primaryCandidate != null) {
return primaryCandidate;
}
// 2.根据@Priority注解来选择最优解
String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
if (priorityCandidate != null) {
return priorityCandidate;
}
// Fallback
// 3.如果通过以上两步都不能选择出最优解,则使用最基本的策略
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateName = entry.getKey();
Object beanInstance = entry.getValue();
// 3.1 containsValue:首先如果这个beanInstance已经由Spring注册过依赖关系,则直接使用该beanInstance作为最优解,
// 3.2 matchesBeanName:如果没有注册过此beanInstance的依赖关系,则根据参数名称来匹配,
// 如果参数名称和某个候选者的beanName或别名一致,那么直接将此bean作为最优解
if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
matchesBeanName(candidateName, descriptor.getDependencyName())) {
return candidateName;
}
}
// 4.没有找到匹配的候选者,则返回null
return null;
}
protected boolean matchesBeanName(String beanName, String candidateName) {
// candidateName与beanName相等 || beanName有别名与candidateName相等,则返回true
return (candidateName != null &&
(candidateName.equals(beanName) || ObjectUtils.containsElement(getAliases(beanName), candidateName)));
}
2、determinePrimaryCandidate
遍历所有候选者,根据@Primary注解来选择最优解。
protected String determinePrimaryCandidate(Map<String, Object> candidates, Class<?> requiredType) {
String primaryBeanName = null;
// 1.遍历所有候选者
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateBeanName = entry.getKey();
Object beanInstance = entry.getValue();
// 2.判断候选者bean是否使用了@Primary注解:如果candidateBeanName在当前BeanFactory中存在BeanDefinition,
// 则判断当前BeanFactory中的BeanDefinition是否使用@Primary修饰;否则,在parentBeanFactory中判断
if (isPrimary(candidateBeanName, beanInstance)) {
if (primaryBeanName != null) {
// 3.走到这边primaryBeanName不为null,代表标识了@Primary的候选者不止一个,则判断BeanName是否存在于当前BeanFactory
// candidateLocal:candidateBeanName是否在当前BeanFactory的beanDefinitionMap缓存中
boolean candidateLocal = containsBeanDefinition(candidateBeanName);
// primaryLocal:primaryBeanName是否在当前BeanFactory的beanDefinitionMap缓存中
boolean primaryLocal = containsBeanDefinition(primaryBeanName);
if (candidateLocal && primaryLocal) {
// 3.1 如果当前BeanFactory中同一个类型的多个Bean,不止一个Bean使用@Primary注解,则抛出异常
throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
"more than one 'primary' bean found among candidates: " + candidates.keySet());
} else if (candidateLocal) {
// 3.2 candidateLocal为true,primaryLocal为false,则代表primaryBeanName是parentBeanFactory中的Bean,
// candidateBeanName是当前BeanFactory中的Bean,当存在两个都使用@Primary注解的Bean,优先使用当前BeanFactory中的
primaryBeanName = candidateBeanName;
}
// 3.3 candidateLocal为false,primaryLocal为true,则代表primaryBeanName是当前BeanFactory中的Bean,
// candidateBeanName是parentBeanFactory中的Bean,因此无需修改primaryBeanName的值
} else {
// 4.primaryBeanName还为空,代表是第一个符合的候选者,直接将primaryBeanName赋值为candidateBeanName
primaryBeanName = candidateBeanName;
}
}
}
// 5.返回唯一的使用@Primary注解的Bean的beanName(如果都没使用@Primary注解则返回null)
return primaryBeanName;
}
3、determineHighestPriorityCandidate
遍历所有候选者,根据@Priority注解来选择最优解。
protected String determineHighestPriorityCandidate(Map<String, Object> candidates, Class<?> requiredType) {
// 用来保存最高优先级的beanName
String highestPriorityBeanName = null;
// 用来保存最高优先级的优先级值
Integer highestPriority = null;
// 1.遍历所有候选者
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateBeanName = entry.getKey();
Object beanInstance = entry.getValue();
// 2.拿到beanInstance的优先级
Integer candidatePriority = getPriority(beanInstance);
if (candidatePriority != null) {
if (highestPriorityBeanName != null) {
// 3.如果之前已经有候选者有优先级,则进行选择
if (candidatePriority.equals(highestPriority)) {
// 3.1 如果存在两个优先级相同的Bean,则抛出异常
throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
"Multiple beans found with the same priority ('" + highestPriority +
"') among candidates: " + candidates.keySet());
} else if (candidatePriority < highestPriority) {
// 3.2 使用优先级值较小的Bean作为最优解(值越低,优先级越高)
highestPriorityBeanName = candidateBeanName;
highestPriority = candidatePriority;
}
} else {
// 4.第一次有候选者有优先级
highestPriorityBeanName = candidateBeanName;
highestPriority = candidatePriority;
}
}
}
// 5.返回优先级最高的bean的beanName
return highestPriorityBeanName;
}
4、storeCache
将解析的构造函数和参数放到缓存。
public void storeCache(RootBeanDefinition mbd, Object constructorOrFactoryMethod) {
synchronized (mbd.constructorArgumentLock) {
// 将构造函数或工厂方法放到resolvedConstructorOrFactoryMethod缓存
mbd.resolvedConstructorOrFactoryMethod = constructorOrFactoryMethod;
// constructorArgumentsResolved标记为已解析
mbd.constructorArgumentsResolved = true;
if (this.resolveNecessary) {
// 如果参数需要解析,则将preparedArguments放到preparedConstructorArguments缓存
mbd.preparedConstructorArguments = this.preparedArguments;
} else {
// 如果参数不需要解析,则将arguments放到resolvedConstructorArguments缓存
mbd.resolvedConstructorArguments = this.arguments;
}
}
}