相关源码注释
ApplicationContext
Spring 5 DefaultResourceLoader 源码注释
Spring 5 AbstractApplicationContext 源码注释
BeanFactory
Spring 5 SimpleAliasRegistry 源码注释
Spring 5 DefaultSingletonBeanRegistry 源码注释
Spring 5 FactoryBeanRegistrySupport 源码注释
Spring 5 AbstractBeanFactory 源码注释
Spring 5 AbstractAutowireCapableBeanFactory 源码注释
Spring 5 DefaultLisbaleBeanFactory 源码注释
AbstractAutowireCapableBeanFactory # resolveBeanClass
从工厂方法确定给定bean定义的目标类型,仅在尚未为目标bean注册单例实例时调用:
- 获取mbd的工厂方法返回类型【RootBeanDefinition#factoryMethodReturnType】,获取成功就返回出去
- 定一个通用返回类型【变量commonType】,用于存储 经过比较 AutowireUtils#resolveReturnTypeForFactoryMethod方法的返回结果 和Method#getReturnType方法的返回结果所得到共同父类。下面步骤都是为了获取commonType所实施的。
- 尝试获取bean的合并bean定义中的缓存用于自省的唯一工厂方法对象【RootBeanDefinition#factoryMethodToIntrospect】 【变量uniqueCandidate】,没成功获取到uniqueCandidate就通过下面步骤获取:
- 定义一个mbd指定的工厂类【变量factoryClass】
- 定义一个表明uniqueCandidate是否是静态方法的标记,默认是true【变量isStatic】
- 获取mbd的FactoryBean名【变量factoryBeanName】
- 如果获取成功,就意味着需要得到factoryBeanName所指的实例对象才能调用uniqueCandidate, 即uniqueCandidate不是静态方法:
- 如果factoryBeanName与beanName相等,会抛出BeanDefinitionStoreException,表明FactoryBean引用指向 相同的BeanDefinition
- 调用getType(factoryBeanName)获取其对应的类型【变量factoryClass】
- isStatic设置为false,表示uniqueCandidate不是静态方法
- 否则,调用resolveBeanClass(mbd, beanName, typesToMatch)来得到factoryClass
- 如果获取成功,就意味着需要得到factoryBeanName所指的实例对象才能调用uniqueCandidate, 即uniqueCandidate不是静态方法:
- 如果经过上面步骤,factoryClass还是没有成功获取就返回null,表示找到不明确的返回类型
- 如果mbd有配置构造函数参数值,就获取该构造函数参数值的数量,否则为0【变量 minNrOfArgs】
- 从该工厂的缓存候选工厂方法集合【factoryMethodCandidateCache】中获取候选方法,如果没有就调用 ReflectionUtils.getUniqueDeclaredMethods(factoryClass, ReflectionUtils.USER_DECLARED_METHODS))来 获取并添加到factoryMethodCandidateCache中【变量 candidates】
- 遍历candidates,元素为candidate.当candidate是否静态的判断结果与isStatic一致 且 candidate有资格作为工厂方法 且candidate的方法参数数量>=minNrOfArgs时:
- 如果candidate的参数数量>0:
- 获取candidate的参数类型数组【变量 paramTypes】
- 使用该工厂的参数名发现器【parameterNameDiscoverer】获取candidate的参数名 【变量 paramNames】
- 获取mbd的构造函数参数值 【变量 cav】
- 定义一个存储构造函数参数值ValueHolder对象的HashSet【变量 usedValueHolders】
- 定义一个用于存储参数值的数组【变量 args】
- 遍历args,索引为i:
- 获取第i个构造函数参数值ValueHolder对象【变量 valueHolder】,尽可能的提供位置,参数类型,参数名 以最精准的方式获取获取第i个构造函数参数值ValueHolder对象,传入usedValueHolder来提示cav#getArgumentValue方法 不应再次返回该usedValueHolder所出现的ValueHolder对象(如果有 多个类型的通用参数值,则允许返回下一个通用参数匹配项)
- 如果valueHolder获取失败,使用不匹配类型,不匹配参数名的方式获取除userValueHolders以外的 下一个参数值valueHolder对象
- 如果valueHolder获取成功,从valueHolder中获取值保存到args[i],然后将valueHolder添加到usedValueHolders缓存中, 表示该valueHolder已经使用过
- 调用AutowireUtils.resolveReturnTypeForFactoryMethod(candidate, args, getBeanClassLoader())获取 candidate的最终返回类型
- 如果commnType为null 且 returnType等于candidate直接获取的返回类型,uniqueCandidate就是candiate,否则为null
- 如果commonType为null就返回null,表示找到不明确的返回类型
- 捕捉获取commonType的所有异常,不再抛出任何异常,只打印出调试日志无法为工厂方法解析通用返回类型
- 如果candidate无需参数:
- 如果还没有找到commonType,candidate就为uniqueCandidate
- 获取candidate返回类型与commonType的共同父类,将该父类重新赋值给commonType
- 如果commonType为null就返回null,表示找到不明确的返回类型
- 如果candidate的参数数量>0:
- 缓存uniqueCandidate到mbd的factoryMethodToInstropect
- 如果commonType为null就返回null,表示找到不明确的返回类型。加上这个判断能保证下面的步骤commonType肯定有值
- 如果获取到了uniqueCandidate就获取uniqueCandidate的返回类型,否则就用commonType作为返回类型【变量cachedReturnType】
- 缓存cachedReturnType到mdb的factoryMethodReturnType
- 返回cachedReturnType封装的Class对象
/**
* Determine the target type for the given bean definition which is based on
* a factory method. Only called if there is no singleton instance registered
* for the target bean already.
* <p>工厂方法确定给定bean定义的目标类型。仅在尚未为目标bean注册单例实例时调用</p>
* <p>This implementation determines the type matching {@link #createBean}'s
* different creation strategies. As far as possible, we'll perform static
* type checking to avoid creation of the target bean.
* <p>此实现确定与createBean的不同创建策略匹配的类型。尽可能地,我们将执行静态类型
* 检查以避免创建目标bean</p>
* @param beanName the name of the bean (for error handling purposes)
* -- bean名(用于错误处理)
* @param mbd the merged bean definition for the bean
* -- bean的合并bean定义
* @param typesToMatch the types to match in case of internal type matching purposes
* (also signals that the returned {@code Class} will never be exposed to application code)
* -- 内部类型匹配时要匹配的类型(也表示返回的Class永远不会暴露给应用程序代码)
* @return the type for the bean if determinable, or {@code null} otherwise
* -- Bean类型(如果可以确定的话),否则为 null
* @see #createBean
*/
@Nullable
protected Class<?> getTypeForFactoryMethod(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
//尝试获取bean的合并bean定义中的缓存工厂方法返回类型
ResolvableType cachedReturnType = mbd.factoryMethodReturnType;
//如果成功获取到了bean的合并bean定义中的缓存工厂方法返回类型
if (cachedReturnType != null) {
//ResolvableType.resolve:将ResolvableType对象解析为Class,如果无法解析,则返回null
return cachedReturnType.resolve();
}
//通用的返回类型,经过比较 AutowireUtils#resolveReturnTypeForFactoryMethod方法的返回结果
// 和Method#getReturnType方法的返回结果所得到共同父类。
Class<?> commonType = null;
//尝试获取bean的合并bean定义中的缓存用于自省的唯一工厂方法对象
Method uniqueCandidate = mbd.factoryMethodToIntrospect;
//如果成功获取到了bean的合并bean定义中的缓存用于自省的唯一工厂方法对象
if (uniqueCandidate == null) {
Class<?> factoryClass;
boolean isStatic = true;
//获取bean的合并bean定义的工厂bean名
String factoryBeanName = mbd.getFactoryBeanName();
//如果成功获取到bean的合并bean定义的工厂bean名
if (factoryBeanName != null) {
//如果工厂bean名 与 生成该bean的bean名相等
if (factoryBeanName.equals(beanName)) {
//抛出 当BeanFactory遇到无效的bean定义时引发的异常 :
// 工厂bean引用指向相同的bean定义
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
"factory-bean reference points back to the same bean definition");
}
// Check declared factory method return type on factory class.
// 检查工厂类上声明的工厂方法返回类型
//获取factoryBeanName对应的工厂类
factoryClass = getType(factoryBeanName);
isStatic = false;
}
else {
// Check declared factory method return type on bean class.
// 检查bean类上声明的工厂方法返回类型
//为mbd解析bean类,将bean类名解析为Class引用(如果需要),并将解析后的Class存储在
// mbd中以备将来使用。
factoryClass = resolveBeanClass(mbd, beanName, typesToMatch);
}
//如果mbd指定的工厂类获取失败
if (factoryClass == null) {
//返回null
return null;
}
//如果factoryClass是CGLIB生成的子类,则返回factoryClass的父类,否则直接返回factoryClass
factoryClass = ClassUtils.getUserClass(factoryClass);
// If all factory methods have the same return type, return that type.
// Can't clearly figure out exact method due to type converting / autowiring!
// 如果所有工厂方法都具有相同的返回类型,则返回该类型。
// 由于类型转换/自动装配,无法明确找出确切的方法。
// 如果mbd有配置构造函数参数值,就获取该构造函数参数值的数量,否则为0
int minNrOfArgs =
(mbd.hasConstructorArgumentValues() ? mbd.getConstructorArgumentValues().getArgumentCount() : 0);
//在子类和所有超类上获取一组唯一的已声明方法,即被重写非协变返回类型的方法
// 首先包含子类方法和然后遍历父类层次结构任何方法,将过滤出所有与已包含的方法匹配的签名方法。
Method[] candidates = this.factoryMethodCandidateCache.computeIfAbsent(factoryClass,
clazz -> ReflectionUtils.getUniqueDeclaredMethods(clazz, ReflectionUtils.USER_DECLARED_METHODS));
//遍历候选方法
for (Method candidate : candidates) {
//如果candidate是否静态的判断结果与isStatic一致 且 candidate有资格作为工厂方法 且 candidate的方法参数数量>=minNrOfArgs
if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate) &&
candidate.getParameterCount() >= minNrOfArgs) {
// Declared type variables to inspect?
// 声明要检查的类型变量?
// 如果candidate的参数数量>0
if (candidate.getTypeParameters().length > 0) {
try {
// Fully resolve parameter names and argument values.
// 完全解析参数名称和参数值
// 获取candidate的参数类型数组
Class<?>[] paramTypes = candidate.getParameterTypes();
//参数名数组
String[] paramNames = null;
//获取参数名发现器
ParameterNameDiscoverer pnd = getParameterNameDiscoverer();
//如果pnd不为null
if (pnd != null) {
//使用pnd获取candidate的参数名
paramNames = pnd.getParameterNames(candidate);
}
//获取mbd的构造函数参数值
ConstructorArgumentValues cav = mbd.getConstructorArgumentValues();
// HashSet:HashSet简单的理解就是HashSet对象中不能存储相同的数据,存储数据时是无序的。
// 但是HashSet存储元素的顺序并不是按照存入时的顺序(和List显然不同) 是按照哈希值来存的所以取数据也是按照哈希值取得。
// 定义一个存储构造函数参数值ValueHolder对象的HashSet
Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length);
// 定义一个用于存储参数值的数组
Object[] args = new Object[paramTypes.length];
//遍历参数值
for (int i = 0; i < args.length; i++) {
//获取第i个构造函数参数值ValueHolder对象
//尽可能的提供位置,参数类型,参数名以最精准的方式获取获取第i个构造函数参数值ValueHolder对象,传入
// usedValueHolder来提示cav#getArgumentValue方法不应再次返回该usedValueHolder所出现的ValueHolder对象
// (如果有 多个类型的通用参数值,则允许返回下一个通用参数匹配项)
ConstructorArgumentValues.ValueHolder valueHolder = cav.getArgumentValue(
i, paramTypes[i], (paramNames != null ? paramNames[i] : null), usedValueHolders);
//如果valueHolder获取失败
if (valueHolder == null) {
//使用不匹配类型,不匹配参数名的方式获取除userValueHolders以外的下一个参数值valueHolder对象
valueHolder = cav.getGenericArgumentValue(null, null, usedValueHolders);
}
//如果valueHolder获取成功
if (valueHolder != null) {
//从valueHolder中获取值保存到第i个args元素中
args[i] = valueHolder.getValue();
//将valueHolder添加到usedValueHolders缓存中,表示该valueHolder已经使用过
usedValueHolders.add(valueHolder);
}
}
//获取candidate的最终返回类型,该方法支持泛型情况下的目标类型获取
Class<?> returnType = AutowireUtils.resolveReturnTypeForFactoryMethod(
candidate, args, getBeanClassLoader());
//如果commnType为null 且 returnType等于candidate直接获取的返回类型,唯一候选方法就是candiate,否则为null
uniqueCandidate = (commonType == null && returnType == candidate.getReturnType() ?
candidate : null);
//获取returnType与commonType的共同父类,将该父类重新赋值给commonType
commonType = ClassUtils.determineCommonAncestor(returnType, commonType);
//如果commonType为null
if (commonType == null) {
// Ambiguous return types found: return null to indicate "not determinable".
// 找到不明确的返回类型:返回null表示'不可确定'
return null;
}
}
//捕捉获取commonType的所有异常
catch (Throwable ex) {
if (logger.isDebugEnabled()) {
//无法为工厂方法解析通用返回类型
logger.debug("Failed to resolve generic return type for factory method: " + ex);
}
}
}
//如果candidate无需参数
else {
//如果还没有找到commonType,candidate就为唯一的候选方法
uniqueCandidate = (commonType == null ? candidate : null);
//获取candidate返回类型与commonType的共同父类,将该父类重新赋值给commonType
commonType = ClassUtils.determineCommonAncestor(candidate.getReturnType(), commonType);
//如果commonType为null
if (commonType == null) {
// Ambiguous return types found: return null to indicate "not determinable".
// 找到不明确的返回类型:返回null表示'不可确定'
return null;
}
}
}
}
//缓存uniqueCandidate到mbd的factoryMethodToInstropect
mbd.factoryMethodToIntrospect = uniqueCandidate;
//如果commonType为null,加上这个判断能保证下面的步骤commonType肯定有值
if (commonType == null) {
// 找到不明确的返回类型:返回null表示'不可确定'
return null;
}
}
// Common return type found: all factory methods return same type. For a non-parameterized
// unique candidate, cache the full type declaration context of the target factory method.
// 找到常见的返回类型:所有工厂方法都返回相同的类型。对象非参数化的唯一候选者,缓存目标工厂方法的
// 完整类型声明上下文
//如果获取到了uniqueCandidate就获取uniqueCandidate的返回类型,否则就用commonType作为返回类型
cachedReturnType = (uniqueCandidate != null ?
ResolvableType.forMethodReturnType(uniqueCandidate) : ResolvableType.forClass(commonType));
//缓存cachedReturnType到mdb的factoryMethodReturnType
mbd.factoryMethodReturnType = cachedReturnType;
//返回cachedReturnType封装的Class对象
return cachedReturnType.resolve();
}
getType(factoryBeanName);
确定具有给定名称的bean类型(为了确定其对象类型,默认让FactoryBean以初始化)。
resolveBeanClass(mbd, beanName, typesToMatch);
为mdb解析出对应的bean class
ClassUtils.getUserClass(factoryClass);
如果clazz是CGLIB生成的子类,则返回该子类的父类,否则直接返回要检查的类
/**
* Return the user-defined class for the given class: usually simply the given
* class, but the original class in case of a CGLIB-generated subclass.
* <p>
* 返回给定实例的用户定义类:通常给定的实例是简单的类,但是在一个CGLIB生成的子类
* 情况下,则是原始类
* </p>
* @param clazz the class to check 检查类
* @return the user-defined class 用户定义的
*/
public static Class<?> getUserClass(Class<?> clazz) {
//如果clazz的全类名包含'$$'字符串,表示它有可能是GGLIB生成的子类
if (clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) {
//获取clazz的父类
Class<?> superclass = clazz.getSuperclass();
//如果superclass不为null 且 superclass不是Object
if (superclass != null && superclass != Object.class) {
//直接返回父类
return superclass;
}
}
//直接返回检查类
return clazz;
}
ReflectionUtils.getUniqueDeclaredMethods(clazz, ReflectionUtils.USER_DECLARED_METHODS)
getParameterNameDiscoverer()
/**
* Resolver strategy for method parameter names.
* <p>方法参数的解析策略</p>
* */
@Nullable
private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
/**
* Return the ParameterNameDiscoverer to use for resolving method parameter
* names if needed.
* <p>如果需要,返回ParameterNameDiscover来解析方法参数名称</p>
*/
@Nullable
protected ParameterNameDiscoverer getParameterNameDiscoverer() {
return this.parameterNameDiscoverer;
}