根据类型查找所有候选Bean
org.springframework.beans.factory.support.DefaultListableBeanFactory#findAutowireCandidates
protected Map<String, Object> findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
//1. 从BeanFactory中找出和requiredType所匹配的beanName,仅仅是beanName,这些bean不一定经过了实例化
//descriptor.isEager():返回此依赖项是否为“急切的”,即急切地解析潜在的目标bean以进行类型匹配。
//处理比如FactoryBean的情况,真正的类型肯定不是FactoryBean.class
//所以获取真正的类型,就会需要初始化FactoryBean
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = CollectionUtils.newLinkedHashMap(candidateNames.length);
//2. 根据类型从resolvableDependencies中匹配,resolvableDependencies中存放的是 类型:bean对象
//类似一个缓存,在Spring启动的时候会赋值
//事先指定 类型 和 实例 的映射关系,只要是注入这个类型,就用这个类型对应的实例进行注入
for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
Class<?> autowiringType = classObjectEntry.getKey();
//requiredType如果是autowiringType子类 或 本身
if (autowiringType.isAssignableFrom(requiredType)) {
Object autowiringValue = classObjectEntry.getValue();
//根据给定的所需类型解析给定的自动装配值,例如ObjectFactory值到其实际对象结果。
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
if (requiredType.isInstance(autowiringValue)) {
//满足条件,往结果集添加
//这种方式bean是没有名字的,所以要利用ObjectUtils.identityToString生成
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
//从所匹配的beanName中继续过滤判断,能不能自动注入
for (String candidate : candidateNames) {
//3. isSelfReference:判断是不是自己注入自己
//4. isAutowireCandidate:判断能不能注入
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
//5.添加到结果集
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
// 为空要么是真的没有匹配的,要么是匹配的自己
if (result.isEmpty()) {
// 是否是多匹配,即需要匹配的类型是不是Map、数组、集合之类的
boolean multiple = indicatesMultipleBeans(requiredType);
// Consider fallback matches if the first pass failed to find anything...
// 如果第一次传递找不到任何东西,请考虑回退匹配。。。
// 6.回退匹配
DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
for (String candidate : candidateNames) {
//3. isSelfReference:判断是不是自己注入自己
//4. isAutowireCandidate:判断能不能注入,回退匹配
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&
(!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
//5.回退匹配成功,添加到结果集
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
//还是没有匹配成功的,尝试匹配自己
if (result.isEmpty() && !multiple) {
// Consider self references as a final pass...
// but in the case of a dependency collection, not the very same bean itself.
// 将自引用视为最后一次传递……但在依赖项集合的情况下,不是同一个bean本身。
for (String candidate : candidateNames) {
//3. isSelfReference:判断是不是自己注入自己
if (isSelfReference(beanName, candidate) &&
(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
//4. isAutowireCandidate:判断能不能注入,自己注入自己的情况
isAutowireCandidate(candidate, fallbackDescriptor)) {
//5.添加到结果集
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
}
}
return result;
}
1. 从BeanFactory中找出和requiredType所匹配的beanName
从BeanFactory中找出和required所匹配的beanName,仅仅是beanName,这些bean不一定经过了实例化
org.springframework.beans.factory.BeanFactoryUtils#beanNamesForTypeIncludingAncestors(org.springframework.beans.factory.ListableBeanFactory, java.lang.Class<?>, boolean, boolean)
public static String[] beanNamesForTypeIncludingAncestors(
ListableBeanFactory lbf, Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
//includeNonSingletons:是否也包含原型bean或作用域bean,还是只包含单例bean(也适用于FactoryBeans)
//此时includeNonSingletons=true
Assert.notNull(lbf, "ListableBeanFactory must not be null");
//从本容器中找
String[] result = lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
//从父容器找并放入result
if (lbf instanceof HierarchicalBeanFactory) {
HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;
if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
String[] parentResult = beanNamesForTypeIncludingAncestors(
(ListableBeanFactory) hbf.getParentBeanFactory(), type, includeNonSingletons, allowEagerInit);
//合并父容器的结果
result = mergeNamesWithParent(result, parentResult, hbf);
}
}
return result;
}
lbf.getBeanNamesForType实现在:
org.springframework.beans.factory.support.DefaultListableBeanFactory#getBeanNamesForType(java.lang.Class<?>, boolean, boolean)
public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
//如果没有冻结,就根据类型去BeanFactory找,如果冻结了,可能就跳过这个if然后去缓存中去拿了
//configurationFrozen:是否可以为所有bean 缓存 bean定义元数据。
if (!isConfigurationFrozen() || type == null || !allowEagerInit) {
return doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit);
}
//从缓存取
//includeNonSingletons:是否也包含原型bean或作用域bean,还是只包含单例bean(也适用于FactoryBeans)
//此时true,所有
Map<Class<?>, String[]> cache =
(includeNonSingletons ? this.allBeanNamesByType : this.singletonBeanNamesByType);
String[] resolvedBeanNames = cache.get(type);
if (resolvedBeanNames != null) {
return resolvedBeanNames;
}
//缓存没有再次加载
resolvedBeanNames = doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true);
if (ClassUtils.isCacheSafe(type, getBeanClassLoader())) {
//缓存
cache.put(type, resolvedBeanNames);
}
return resolvedBeanNames;
}
注意,ResolvableType.forRawClass(type),当前链路把class的泛型去掉了,只会对原始类进行可分配性检查:
简单来说接下来匹配不会考虑泛型。
//返回指定Class的ResolvableType,仅对原始类进行可分配性检查
public static ResolvableType forRawClass(@Nullable Class<?> clazz) {
return new ResolvableType(clazz) {
@Override
public ResolvableType[] getGenerics() {
//这里去掉了泛型的情况!!
return EMPTY_TYPES_ARRAY;
}
@Override
public boolean isAssignableFrom(Class<?> other) {
//isAssignable:检查右侧类型是否可以分配给左侧类型
return (clazz == null || ClassUtils.isAssignable(clazz, other));
}
@Override
public boolean isAssignableFrom(ResolvableType other) {
Class<?> otherClass = other.resolve();
return (otherClass != null && (clazz == null || ClassUtils.isAssignable(clazz, otherClass)));
}
};
}
核心doGetBeanNamesForType
注意入参allowEagerInit的含义:
是否允许急切初始化:为类型检查,是否初始化 懒加载的单例Bean对象 和 由FactoryBeans(或由带有“factory-bean”引用的工厂方法)创建的对象。请注意,factorybean需要紧急初始化以确定它们的类型:因此请注意,为该标志传入“true”将初始化factorybean和“factory-bean”引用。
private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
List<String> result = new ArrayList<>();
// Check all bean definitions.
// 遍历所有BeanDefinition的名字(beanDefinitionNames不会包含"&xxx"的)
for (String beanName : this.beanDefinitionNames) {
// Only consider bean as eligible if the bean name is not defined as alias for some other bean.
// 只有当bean名称没有定义为其他bean的别名时,才认为bean是合格的。
if (!isAlias(beanName)) {//只处理规范的BeanName
try {
//拿到合并后的RootBeanDefinition
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// Only check bean definition if it is complete.
//1.1 判断mbd允不允许解析对应的类型
//首先mdb不能是抽象的
//然后allowEagerInit为true,说明允许立即初始化,那接下来就去推测解析mdb的类型,并进行匹配
//如果allowEagerInit为false,说明不允许立即初始化,但出现以下情况也可以继续去推测类型:
// 需要同时满足a和b:
// a.以下三个条件满足其一:
// mbd.hasBeanClass():是否已经加载过类了
// mbd.isLazyInit():返回该bean是否应该延迟初始化,即在启动时不急于实例化。只适用于单例bean。(是不是懒加载的)
// isAllowEagerClassLoading():返回是否允许工厂紧急加载bean类,即使对于标记为“lazy-init”的bean定义也是如此。
//
// 即已经加载过类、或者非懒加载的mdb、或者工厂允许紧急加载bean类
// b.requiresEagerInitForType:检查指定的bean是否需要紧急初始化以确定其类型。
// 什么情况需要紧急初始化?当前beanName是FactoryBean,且FactoryBean本身还没有实例化的时候
if (!mbd.isAbstract() && (allowEagerInit ||
(mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&
!requiresEagerInitForType(mbd.getFactoryBeanName()))) {
boolean isFactoryBean = isFactoryBean(beanName, mbd);
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
boolean matchFound = false;
//是否允许FactoryBean初始化
//containsSingleton(beanName)=true,说明之前已经初始化过了
boolean allowFactoryBeanInit = (allowEagerInit || containsSingleton(beanName));
//是否是非懒加载的
boolean isNonLazyDecorated = (dbd != null && !mbd.isLazyInit());
//当前BeanDefinition不是FactoryBean,就是普通Bean
if (!isFactoryBean) {
//在筛选Bean时,如果仅仅只包括单例,但是BeanName对应的又不是单例,则会忽略
if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
//1.2 类型匹配
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
}
}
//FactoryBean情况:
else {
//includeNonSingletons:是否也包含原型bean或作用域bean,还是只包含单例bean(也适用于FactoryBeans)
//isNonLazyDecorated:是否是非懒加载的
//允许FactoryBean初始化并且BeanName对应的是单例
//常规引用匹配,先尝试匹配FactoryBean背后真正的类型
if (includeNonSingletons || isNonLazyDecorated ||
(allowFactoryBeanInit && isSingleton(beanName, mbd, dbd))) {
//1.2 类型匹配
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
}
//如果匹配失败,进行FactoryBean引用匹配
//有可能type是FactoryBean本身的类型,希望匹配的是FactoryBean自己的实例
if (!matchFound) {
// In case of FactoryBean, try to match FactoryBean instance itself next.
// 对于FactoryBean,接下来尝试匹配FactoryBean实例本身
beanName = FACTORY_BEAN_PREFIX + beanName;
if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
//1.2 类型匹配
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
}
}
}
if (matchFound) {
//匹配成功添加到结果集
result.add(beanName);
}
}
}
catch (CannotLoadBeanClassException | BeanDefinitionStoreException ex) {...}
catch (NoSuchBeanDefinitionException ex) {...}
}
}
// Check manually registered singletons too.
// 还要检查手动注册的单例
for (String beanName : this.manualSingletonNames) {
try {
// In case of FactoryBean, match object created by FactoryBean.
if (isFactoryBean(beanName)) {
//处理FactoryBean的情况
//常规引用匹配
if ((includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type)) {//1.2 类型匹配 isTypeMatch
result.add(beanName);
// Match found for this bean: do not match FactoryBean itself anymore.
// 为该bean找到匹配:不再匹配FactoryBean本身。
continue;
}
//FactoryBean引用匹配
// In case of FactoryBean, try to match FactoryBean itself next.
// 对于FactoryBean,接下来尝试匹配FactoryBean实例本身
beanName = FACTORY_BEAN_PREFIX + beanName;
}
// Match raw bean instance (might be raw FactoryBean).
// 匹配原始bean实例(可能是原始FactoryBean)。
//1.2 类型匹配
if (isTypeMatch(beanName, type)) {
result.add(beanName);
}
}
catch (NoSuchBeanDefinitionException ex) {...}
}
//最终返回一个结果
return StringUtils.toStringArray(result);
}
1.1 判断BeanDefinition允不允许解析对应的类型
有一段复杂的判断逻辑:
首先mdb不能是抽象的。
其次要知道,allowEagerInit的含义:
- 为了类型检查,是否初始化 懒加载的单例Bean对象 和 由FactoryBeans (或由带有“factory-bean”引用的工厂方法)创建的对象。请注意,factorybean需要紧急初始化以确定它们的类型:因此请注意,为该标志传入“true”将初始化factorybean和“factory-bean”引用。
如果allowEagerInit为true,说明允许立即初始化,那接下来就去推测解析mdb的类型。
如果allowEagerInit为false,说明不允许立即初始化,但出现以下情况也可以继续去推测类型,需要同时满足a和b:
org.springframework.beans.factory.support.DefaultListableBeanFactory#requiresEagerInitForType
private boolean requiresEagerInitForType(@Nullable String factoryBeanName) {
//如果是FactoryBean情况,FactoryBean本身如果还没有初始化过,会返回true
return (factoryBeanName != null && isFactoryBean(factoryBeanName) && !containsSingleton(factoryBeanName));
}
整个条件看上去有点复杂,但是如果只是考虑大部分流程,则可以忽略这个判断,因为allowEagerInit传进来的基本上都是true
1.2 类型匹配
org.springframework.beans.factory.support.AbstractBeanFactory#isTypeMatch(java.lang.String, org.springframework.core.ResolvableType, boolean)
//判断name所对应的Bean类型是不是typeToMatch,name有可能是&xxx工厂引用
protected boolean isTypeMatch(String name, ResolvableType typeToMatch, boolean allowFactoryBeanInit)
throws NoSuchBeanDefinitionException {
//allowFactoryBeanInit表示允不允许在这里实例化FactoryBean的对象,以获取真正的类型
//获取规范的BeanName,如果name是&xxx,那beanName就是xxx
String beanName = transformedBeanName(name);
//判断name是不是对FactoryBean工厂引用(判断name是不是&开头)
boolean isFactoryDereference = BeanFactoryUtils.isFactoryDereference(name);
// Check manually registered singletons.
// 先尝试从单例池直接获取bean实例
Object beanInstance = getSingleton(beanName, false);
if (beanInstance != null && beanInstance.getClass() != NullBean.class) {
//单例池获取成功,说明这个Bean已经实例化过了
if (beanInstance instanceof FactoryBean) {
//拿到实例是FactoryBean情况
if (!isFactoryDereference) {
//常规引用,希望拿到是FactoryBean背后真实对象的类型
//而FactoryBean本身已经实例化了,所以直接调用factoryBean.getObjectType拿到类型
//a.获取FactoryBean创建的对象类型
Class<?> type = getTypeForFactoryBean((FactoryBean<?>) beanInstance);
return (type != null && typeToMatch.isAssignableFrom(type));
}
else {
//FactoryBean引用,希望拿到FactoryBean本身的类型进行匹配
return typeToMatch.isInstance(beanInstance);
}
}
//单例池拿到的不是FactoryBean,并且是常规引用,希望获取真实对象类型进行匹配
else if (!isFactoryDereference) {
//直接匹配实例
if (typeToMatch.isInstance(beanInstance)) {
// Direct match for exposed instance?
// 直接匹配公开的实例
return true;
}
//直接匹配实例没成功,判断参数类型是不是带泛型,如果是会特殊处理
//b.泛型可能仅在目标类上匹配,而在代理上不匹配
//jdk动态代理+泛型的时候,泛型可能仅在目标类上匹配,而在代理上不匹配
//typeToMatch.hasGenerics():如果此类型包含泛型参数则返回true。
else if (typeToMatch.hasGenerics() && containsBeanDefinition(beanName)) {
// Generics potentially only match on the target class, not on the proxy...
// 泛型可能仅在目标类上匹配,而在代理(代理实例)上不匹配
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//从BeanDefinition上获取目标类型(获取的是提前指定的目标类型,或是第一次实例化时解析的类型)
//有可能为null,说明是工厂方法的情况
Class<?> targetType = mbd.getTargetType();
//targetType不为null的话,和实例类型进行比较,不一样,说明可能是jdk动态代理的实例
//ClassUtils.getUserClass(beanInstance):返回给定实例的用户定义类:通常只是给定实例的类,但如果是CGLIB生成的子类,则返回原始类。
if (targetType != null && targetType != ClassUtils.getUserClass(beanInstance)) {
// Check raw class match as well, making sure it's exposed on the proxy.
// 同时检查原始类匹配,确保它在代理上公开
// 此时beanInstance应该是一个jdk动态代理的对象
//typeToMatch.resolve:将类型解析为Class
//如果无法解析该类型,则返回null。
//如果直接解析失败,此方法将考虑TypeVariables和WildcardTypes的边界;但是,Object.class的边界将被忽略。
//因为事先检查过typeToMatch带泛型,
//应该是Xxx<T>类似这种类型,而resovle返回值就是Xxx.Class
Class<?> classToMatch = typeToMatch.resolve();
if (classToMatch != null && !classToMatch.isInstance(beanInstance)) {
//判断jdk动态代理对象,是不是Xxx.Class类型,不是直接返回false
return false;
}
//根据BeanDefinition上的目标类型进行判断
//typeToMatch.isAssignableFrom:确定此ResolvableType是否可从指定的其他类型分配。
//即检查右侧类型targetType是否可以分配给左侧类型typeToMatch
//即判断targetType是不是typeToMatch,或者是typeToMatch的子类
if (typeToMatch.isAssignableFrom(targetType)) {
return true;
}
}
//mbd.targetType为null,说明是工厂方法的情况
ResolvableType resolvableType = mbd.targetType;
if (resolvableType == null) {
//获取工厂方法的返回值类型
resolvableType = mbd.factoryMethodReturnType;
}
//目标类匹配(带泛型的匹配)
return (resolvableType != null && typeToMatch.isAssignableFrom(resolvableType));
}
}
//单例池拿到了非null Bean,但是匹配能尝试的都尝试了,最终返回false
return false;
}
else if (containsSingleton(beanName) && !containsBeanDefinition(beanName)) {
// null instance registered
// NullBean的情况,直接返回false
return false;
}
// 走到这说明没有从单例池获取到实例
// No singleton instance found -> check bean definition.
// 检查一下当前容器有没有这个definition,没有就从父容器里判断
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// No bean definition found in this factory -> delegate to parent.
return parentBeanFactory.isTypeMatch(originalBeanName(name), typeToMatch);
}
//单例池中没有name对应的Bean对象,就只能根据BeanDefinition来判断出类型了
// Retrieve corresponding bean definition.
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
// Set up the types that we want to match against
// 设置要匹配的类型
Class<?> classToMatch = typeToMatch.resolve();
if (classToMatch == null) {
classToMatch = FactoryBean.class;
}
//typesToMatch至少包含一个FactoryBean类型,为了处理FactoryBean引用的情况
Class<?>[] typesToMatch = (FactoryBean.class == classToMatch ?
new Class<?>[] {classToMatch} : new Class<?>[] {FactoryBean.class, classToMatch});
// Attempt to predict the bean type
// 尝试预测bean Class类型
Class<?> predictedType = null;
// We're looking for a regular reference but we're a factory bean that has
// a decorated bean definition. The target bean should be the same type
// as FactoryBean would ultimately return.
//我们正在寻找常规引用,但我们是一个具有装饰bean定义的工厂bean。
//目标bean应该与FactoryBean最终返回的类型相同
if (!isFactoryDereference && dbd != null && isFactoryBean(beanName, mbd)) {
// We should only attempt if the user explicitly set lazy-init to true
// and we know the merged bean definition is for a factory bean.
//非懒加载Bean、或允许FactoryBean初始化
if (!mbd.isLazyInit() || allowFactoryBeanInit) {
//获取被装饰的BeanDefinition(应该是工厂Bean背后真正类型的Bean定义吧??)
RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd);
//使用装饰的BeanDefinition推断类型
//常规引用,希望拿到FactoryBean最终返回的类型
//c. 推断bean Class类型,获取目标类型
Class<?> targetType = predictBeanType(dbd.getBeanName(), tbd, typesToMatch);
if (targetType != null && !FactoryBean.class.isAssignableFrom(targetType)) {
//不为null,且不是FactoryBean,说明成功推断出FactoryBean最终返回的类型
predictedType = targetType;
}
}
}
// If we couldn't use the target type, try regular prediction.
// 如果我们不能使用(FactoryBean的?)目标类型,尝试常规预测。
if (predictedType == null) {
//c. 推断bean Class类型
predictedType = predictBeanType(beanName, mbd, typesToMatch);
if (predictedType == null) {
//推断失败,直接返回false
return false;
}
}
// Attempt to get the actual ResolvableType for the bean.
// 尝试获取bean的实际ResolvableType。
//predictedType是Class,不带泛型
//这里希望推断出ResolvableType,它是带泛型的,更精确匹配
ResolvableType beanType = null;
// If it's a FactoryBean, we want to look at what it creates, not the factory class.
// 如果它是FactoryBean,我们想看看它创建了什么,而不是工厂类。
// predictedType类型如果是FactoryBean,得先实例化FactoryBean这个对象,然后调用getObjectType方法
// 才能知道具体背后对应的类型
if (FactoryBean.class.isAssignableFrom(predictedType)) {
if (beanInstance == null && !isFactoryDereference) {
//d. 先实例化FactoryBean对象,再获取FactoryBean创建的对象类型
beanType = getTypeForFactoryBean(beanName, mbd, allowFactoryBeanInit);
predictedType = beanType.resolve();
if (predictedType == null) {
return false;
}
}
}
//FactoryBean引用的情况
else if (isFactoryDereference) {
// Special case: A SmartInstantiationAwareBeanPostProcessor returned a non-FactoryBean
// type but we nevertheless are being asked to dereference a FactoryBean...
// Let's check the original bean class and proceed with it if it is a FactoryBean.
// 特殊情况:SmartInstantationAwareBeanPostProcessor返回了一个非FactoryBean类型,但我们仍然被要求取消引用FactoryBean...
// 让我们检查原始bean类,如果它是FactoryBean,则继续处理它。
// 简单来说就是当前我们是工厂引用,但是推测类型拿到的类型不是FactoryBean类型(通过SmartInstantationAwareBeanPostProcessor返回的)
// 所以我们拿原始BeanDefintion的类型,判断是不是FactoryBean,不是直接返回false
// 是的话继续处理它
//d. 推断bean Class类型是不是FactoryBean
predictedType = predictBeanType(beanName, mbd, FactoryBean.class);
if (predictedType == null || !FactoryBean.class.isAssignableFrom(predictedType)) {
return false;
}
}
// We don't have an exact type but if bean definition target type or the factory
// method return type matches the predicted type then we can use that.
// 我们没有确切的类型,但如果bean定义目标类型或工厂方法返回类型与预测类型匹配,那么我们可以使用它。
if (beanType == null) {
ResolvableType definedType = mbd.targetType;
if (definedType == null) {
definedType = mbd.factoryMethodReturnType;
}
//比较Class类型,一样,可以用带泛型的definedType替换
if (definedType != null && definedType.resolve() == predictedType) {
beanType = definedType;
}
}
// If we have a bean type use it so that generics are considered
// 如果我们有一个bean类型,请使用它,以便考虑泛型
// (ResolvableType是带泛型的类型!!!!)
if (beanType != null) {
return typeToMatch.isAssignableFrom(beanType);
}
// If we don't have a bean type, fallback to the predicted type
// 如果我们没有bean类型,回退到预测类型
return typeToMatch.isAssignableFrom(predictedType);
}
比较复杂,大体流程分两步
- 先从单例池获取实例,根据实例进行类型判断
- 单例池没有则根据BeanDefinition进行类型判断
a. 获取FactoryBean创建的对象类型
org.springframework.beans.factory.support.FactoryBeanRegistrySupport#getTypeForFactoryBean
protected Class<?> getTypeForFactoryBean(FactoryBean<?> factoryBean) {
try {
if (System.getSecurityManager() != null) {...}
else {
//调用factoryBean.getObjectType()
//获取FactoryBean创建的对象类型
return factoryBean.getObjectType();
}
}
catch (Throwable ex) {...}
}
为什么FactoryBean要单独设计一个getObjectType()方法?
- 因为在判断一个Bean是否是某一个类型的时候,是不希望通过实例化后获取类型的,因为实例化了以后发现类型不匹配,也不会用,浪费。
- 所以getObjectType方法的意义就是不用实例化FactoryBean的getObject对象,就能获取到对应的类型。
b. 泛型可能仅在目标类上匹配,而在代理上不匹配
jdk动态代理+泛型的时候,泛型可能仅在目标类上匹配,而在代理上不匹配,Demo:
public class Test2 {
//具体接口
public interface A {}
//带泛型的接口
public interface Generic<T> {}
//具体实现类,指定了泛型具体类型
public static class GenericA implements Generic<A> {}
//Test2的成员变量,泛型接口+具体泛型类型
private Generic<A> genericA;
public static void main(String[] args) throws NoSuchFieldException {
Field field = Test2.class.getDeclaredField("genericA");
ResolvableType resolvableType = ResolvableType.forField(field);
System.out.println(resolvableType.hasGenerics());//true
//resolve返回的是具体Class类型,不带泛型
System.out.println(resolvableType.resolve());//interface com.yth.Test2$Generic
TargetSource targetSource = new TargetSource() {
@Override
public Class<?> getTargetClass() {
//模拟jdk动态代理,针对接口生成代理类
//接口上是没有具体泛型类型的
return GenericA.class.getInterfaces()[0];
}
@Override
public boolean isStatic() {
return true;
}
@Override
public Object getTarget() throws Exception {
return new GenericA();
}
@Override
public void releaseTarget(Object target) throws Exception {
}
};
Object proxy = ProxyFactory.getProxy(targetSource);
//proxy是jdk动态代理,面对接口生成的代理对象,接口上没有泛型具体类型
//resolvableType.isInstance不仅判断类型,还会判断泛型,所以是false
System.out.println(resolvableType.isInstance(proxy));//false
//GenericA是具体类,在实现类上指定了泛型具体类型了,所以是true
System.out.println(resolvableType.isInstance(new GenericA()));//true
//resolve返回的是Class类型:interface com.yth.Test2$Generic
System.out.println(resolvableType.resolve().isInstance(new GenericA()));//true
System.out.println(resolvableType.resolve().isInstance(proxy));//true
}
}
ResolvableType是带泛型的类型,resolvableType.resolve()返回的是Class类型
c. 推断bean Class类型
真正实现类是org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#predictBeanType
protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
//推测目标类型
Class<?> targetType = determineTargetType(beanName, mbd, typesToMatch);
// Apply SmartInstantiationAwareBeanPostProcessors to predict the
// eventual type after a before-instantiation shortcut.
// 在实例化前快捷方式之后应用SmartInstantationAwareBeanPostProcessors预测最终类型。
if (targetType != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
boolean matchingOnlyFactoryBean = typesToMatch.length == 1 && typesToMatch[0] == FactoryBean.class;
for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
Class<?> predicted = bp.predictBeanType(targetType, beanName);
//推测出来如果不为null,则
//不是只匹配FactoryBean则直接返回
//推测出来的是FactoryBean也直接返回
if (predicted != null &&
(!matchingOnlyFactoryBean || FactoryBean.class.isAssignableFrom(predicted))) {
return predicted;
}
}
}
return targetType;
}
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#determineTargetType
//确定给定bean定义的目标类型,class类型
protected Class<?> determineTargetType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
Class<?> targetType = mbd.getTargetType();
if (targetType == null) {
targetType = (mbd.getFactoryMethodName() != null ?
//1.确定基于工厂方法的给定bean定义的目标Class类型
getTypeForFactoryMethod(beanName, mbd, typesToMatch) :
//2.解析指定bean定义的bean类,将bean类名解析为class引用(如果需要),并将解析的class存储在bean定义中以供进一步使用。
resolveBeanClass(mbd, beanName, typesToMatch));
if (ObjectUtils.isEmpty(typesToMatch) || getTempClassLoader() == null) {
mbd.resolvedTargetType = targetType;
}
}
return targetType;
}
看下普通Bean情况
org.springframework.beans.factory.support.AbstractBeanFactory#resolveBeanClass
protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
throws CannotLoadBeanClassException {
try {
//beanClass已经加载了直接返回
if (mbd.hasBeanClass()) {
return mbd.getBeanClass();
}
if (System.getSecurityManager() != null) {...}
else {
//还没有被加载,则加载
return doResolveBeanClass(mbd, typesToMatch);
}
}
catch (PrivilegedActionException pae) {...}
catch (ClassNotFoundException ex) {...}
catch (LinkageError err) {...}
}
private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
throws ClassNotFoundException {
ClassLoader beanClassLoader = getBeanClassLoader();
ClassLoader dynamicLoader = beanClassLoader;
boolean freshResolve = false;
if (!ObjectUtils.isEmpty(typesToMatch)) {
// When just doing type checks (i.e. not creating an actual instance yet),
// use the specified temporary class loader (e.g. in a weaving scenario).
// 当只进行类型检查(即尚未创建实际实例)时,请使用指定的临时类加载器(例如在编织场景中)。
ClassLoader tempClassLoader = getTempClassLoader();
if (tempClassLoader != null) {
dynamicLoader = tempClassLoader;
freshResolve = true;
//用于装饰ClassLoader的基类,如OverridingClassLoador和ShadowingClassLoader
//提供对排除的包和类的通用处理。
if (tempClassLoader instanceof DecoratingClassLoader) {
DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
for (Class<?> typeToMatch : typesToMatch) {
//添加要从装饰中排除的类名(例如重写)。
//在这里注册的任何类名都将由父ClassLoader以通常的方式处理。
//推测:excludeClass中的class由父类加载器加载,
//其他的类用当前临时类加载器加载
dcl.excludeClass(typeToMatch.getName());
}
}
}
}
String className = mbd.getBeanClassName();
if (className != null) {
//评估bean定义中包含的给定String,可能将其解析为表达式。
//className可能是个Spring表达式
Object evaluated = evaluateBeanDefinitionString(className, mbd);
if (!className.equals(evaluated)) {
//不一样,说明解析成功了,返回值可能直接就是Class,或新的字符串内容
// A dynamically resolved expression, supported as of 4.2...
// 动态解析表达式
if (evaluated instanceof Class) {
return (Class<?>) evaluated;
}
else if (evaluated instanceof String) {
className = (String) evaluated;
freshResolve = true;
}
else {...}
}
if (freshResolve) {
// When resolving against a temporary class loader, exit early in order
// to avoid storing the resolved Class in the bean definition.
// 当针对临时类加载器进行解析时,请提前退出,以避免将解析的类存储在bean定义中。
if (dynamicLoader != null) {
try {
//这里加载直接返回,不会保存到BeanDefinition中
return dynamicLoader.loadClass(className);
}
catch (ClassNotFoundException ex) {...}
}
return ClassUtils.forName(className, dynamicLoader);
}
}
// Resolve regularly, caching the result in the BeanDefinition...
// 常规解析,在BeanDefinition中缓存结果…
return mbd.resolveBeanClass(beanClassLoader);
}
org.springframework.beans.factory.support.AbstractBeanDefinition#resolveBeanClass
public Class<?> resolveBeanClass(@Nullable ClassLoader classLoader) throws ClassNotFoundException {
String className = getBeanClassName();
if (className == null) {
return null;
}
//解析
Class<?> resolvedClass = ClassUtils.forName(className, classLoader);
//缓存到Bean定义中
this.beanClass = resolvedClass;
return resolvedClass;
}
org.springframework.util.ClassUtils#forName
//替换Class.forName(),它还返回原语(例如“int”)和数组类名(例如“String[]”)的类实例。
//此外,它还能够解析Java源代码样式中的嵌套类名(例如“Java.lang.Thread.State”而不是“Java.llang.Thread$State”)。
public static Class<?> forName(String name, @Nullable ClassLoader classLoader)
throws ClassNotFoundException, LinkageError {
Assert.notNull(name, "Name must not be null");
//如果合适,根据JVM的原语类命名规则,将给定的类名解析为原语类。
//还支持基本数组的JVM内部类名。不支持基元数组的“[]”后缀符号;这仅由forName(String,ClassLoader)支持。
Class<?> clazz = resolvePrimitiveClassName(name);
if (clazz == null) {
clazz = commonClassCache.get(name);
}
if (clazz != null) {
return clazz;
}
// "java.lang.String[]" style arrays
if (name.endsWith(ARRAY_SUFFIX)) {
String elementClassName = name.substring(0, name.length() - ARRAY_SUFFIX.length());
Class<?> elementClass = forName(elementClassName, classLoader);
return Array.newInstance(elementClass, 0).getClass();
}
// "[Ljava.lang.String;" style arrays
if (name.startsWith(NON_PRIMITIVE_ARRAY_PREFIX) && name.endsWith(";")) {
String elementName = name.substring(NON_PRIMITIVE_ARRAY_PREFIX.length(), name.length() - 1);
Class<?> elementClass = forName(elementName, classLoader);
return Array.newInstance(elementClass, 0).getClass();
}
// "[[I" or "[[Ljava.lang.String;" style arrays
if (name.startsWith(INTERNAL_ARRAY_PREFIX)) {
String elementName = name.substring(INTERNAL_ARRAY_PREFIX.length());
Class<?> elementClass = forName(elementName, classLoader);
return Array.newInstance(elementClass, 0).getClass();
}
ClassLoader clToUse = classLoader;
if (clToUse == null) {
clToUse = getDefaultClassLoader();
}
try {
//核心
return Class.forName(name, false, clToUse);
}
catch (ClassNotFoundException ex) {...}
}
d. 先实例化FactoryBean对象,再获取FactoryBean创建的对象类型
org.springframework.beans.factory.support.AbstractBeanFactory#getTypeForFactoryBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, boolean)
protected ResolvableType getTypeForFactoryBean(String beanName, RootBeanDefinition mbd, boolean allowInit) {
//先尝试从BeanDefinition的attribute里获取目标类型
ResolvableType result = getTypeForFactoryBeanFromAttributes(mbd);
if (result != ResolvableType.NONE) {
return result;
}
//允许初始化,并且是单例,则实例化FactoryBean后,再获取目标类型
if (allowInit && mbd.isSingleton()) {
try {
//FactoryBean引用,获取FactoryBean自身实例对象
FactoryBean<?> factoryBean = doGetBean(FACTORY_BEAN_PREFIX + beanName, FactoryBean.class, null, true);
//a.获取FactoryBean创建的对象类型
Class<?> objectType = getTypeForFactoryBean(factoryBean);
return (objectType != null ? ResolvableType.forClass(objectType) : ResolvableType.NONE);
}
catch (BeanCreationException ex) {...}
}
return ResolvableType.NONE;
}
2. resolvableDependencies
Spring启动的时候会往这个map赋值
org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory
注入过程中如果这个map中已经存在对应类型key,直接取value进行注入。
自己也可以定义:
3. 判断是不是自己注入自己
org.springframework.beans.factory.support.DefaultListableBeanFactory#isSelfReference
//确定给定的beanName/ccandidateName对是否指示自引用,
//即候选是否指向原始bean或原始bean上的工厂方法。
private boolean isSelfReference(@Nullable String beanName, @Nullable String candidateName) {
return (beanName != null && candidateName != null &&
(beanName.equals(candidateName) || (containsBeanDefinition(candidateName) &&
beanName.equals(getMergedLocalBeanDefinition(candidateName).getFactoryBeanName()))));
}
注入的时候优先考虑别人
4. 判断能不能注入
虽然name对应的类型和要注入的类型是一样的,但是也不一定能注入,比如:
org.springframework.beans.factory.support.DefaultListableBeanFactory#isAutowireCandidate(java.lang.String, org.springframework.beans.factory.config.DependencyDescriptor)
public boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
throws NoSuchBeanDefinitionException {
return isAutowireCandidate(beanName, descriptor, getAutowireCandidateResolver());
}
protected boolean isAutowireCandidate(
String beanName, DependencyDescriptor descriptor, AutowireCandidateResolver resolver)
throws NoSuchBeanDefinitionException {
//根据BeanDefinition判断beanName对应的Bean可不可以用来进行依赖注入
//获取Bean规范名称
String bdName = BeanFactoryUtils.transformedBeanName(beanName);
if (containsBeanDefinition(bdName)) {
//核心方法
return isAutowireCandidate(beanName, getMergedLocalBeanDefinition(bdName), descriptor, resolver);
}
//判断单例池中有没有这个Bean实例(存在有实例,没有BeanDefinition的情况)
else if (containsSingleton(beanName)) {
//核心方法
return isAutowireCandidate(beanName, new RootBeanDefinition(getType(beanName)), descriptor, resolver);
}
//当前工厂,没有这个BeanDefinition,单例池也没有Bean
//则从父工厂判断能否注入
BeanFactory parent = getParentBeanFactory();
if (parent instanceof DefaultListableBeanFactory) {...}
else if (parent instanceof ConfigurableListableBeanFactory) {...}
else {...}
}
protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd,
DependencyDescriptor descriptor, AutowireCandidateResolver resolver) {
String bdName = BeanFactoryUtils.transformedBeanName(beanName);
//解析指定bean定义的bean类,将bean类名解析为class引用(如果需要),
//并将解析的class存储在bean定义中以供进一步使用。
resolveBeanClass(mbd, bdName);
//和@Bean有关系,工厂方法
if (mbd.isFactoryMethodUnique && mbd.factoryMethodToIntrospect == null) {
//给factoryMethodToIntrospect赋值,记录@Bean对应的Method对象
//解析指定bean定义中的工厂方法,RootBeanDefinition.getResolvedFactoryMethod()可以检查结果。
new ConstructorResolver(this).resolveFactoryMethodIfPossible(mbd);
}
BeanDefinitionHolder holder = (beanName.equals(bdName) ?
this.mergedBeanDefinitionHolders.computeIfAbsent(beanName,
key -> new BeanDefinitionHolder(mbd, beanName, getAliases(bdName))) :
new BeanDefinitionHolder(mbd, beanName, getAliases(bdName)));
//核心这
return resolver.isAutowireCandidate(holder, descriptor);
}
resolver真正的类是QualifierAnnotationAutowireCandidateResolver
org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver#isAutowireCandidate
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
//先执行上层父类的判断,如果匹配成功,在由自己匹配
boolean match = super.isAutowireCandidate(bdHolder, descriptor);
if (match) {
//参数级别注解校验
//descriptor.getAnnotations()拿的是属性 或 方法参数 前的注解,拿不到方法上的注解
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()) {
//methodParam.getMethodAnnotations()拿到的是方法上的注解
match = checkQualifiers(bdHolder, methodParam.getMethodAnnotations());
}
}
}
}
return match;
}
QualifierAnnotationAutowireCandidateResolver主要处理@Qualifier注解
QualifierAnnotationAutowireCandidateResolver的父类是GenericTypeAwareAutowireCandidateResolver:处理泛型相关的数据,判断能否注入
GenericTypeAwareAutowireCandidateResolver的父类是SimpleAutowireCandidateResolver:判断BeanDefinition的autowireCandiate属性是否为true
责任链模式。
接下来简单介绍一下,非源码级别,应用级别。
SimpleAutowireCandidateResolver
GenericTypeAwareAutowireCandidateResolver
org.springframework.beans.factory.support.GenericTypeAwareAutowireCandidateResolver#isAutowireCandidate
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
//super就是SimpleAutowireCandidateResolver,判断BeanDefinition的autowireCandiate属性是否为true
if (!super.isAutowireCandidate(bdHolder, descriptor)) {
// If explicitly false, do not proceed with any other checks...
return false;
}
//父类通过,在判断当前类的逻辑,处理泛型相关逻辑
return checkGenericTypeMatch(bdHolder, descriptor);
}
源码就不看了,直接演示一下获取泛型类型的核心API:
public class GenericTest {
@Component
public static class OrderService {}
@Component
public static class StockService {}
public static class BaseService<O, S> {
@Autowired
protected O o;
@Autowired
protected S s;
}
@Component
public static class UserService extends BaseService<OrderService, StockService> {
public void test() {
System.out.println(o);
System.out.println(s);
}
}
public static void main(String[] args) {
// 演示一下获取泛型类型的核心API
UserService userService = new UserService();
Class<?> superclass = userService.getClass().getSuperclass();
// 获取类上定义的泛型变量
for (TypeVariable<? extends Class<?>> typeParameter : superclass.getTypeParameters()) {
System.out.println(typeParameter.getName());
}
// 获取类中成员变量的泛型类型
for (Field declaredField : superclass.getDeclaredFields()) {
System.out.println(declaredField.getGenericType());
}
Type genericSuperclass = userService.getClass().getGenericSuperclass();
// 判断是否是泛型类型
if (genericSuperclass instanceof ParameterizedType) {
System.out.println("是泛型类型");
ParameterizedType parameterizedType = (ParameterizedType)genericSuperclass;
// 获取泛型
for (Type actualTypeArgument : parameterizedType.getActualTypeArguments()) {
System.out.println("泛型类型:" + actualTypeArgument);
}
}
}
}
public class TypeTest<T> {
private int i;
private Integer it;
private int[] iarray;
private List list;
private List<String> slist;
private List<T> tlist;
private T t;
private T[] tarray;
public static void main(String[] args) throws NoSuchFieldException {
test(TypeTest.class.getDeclaredField("i"));
System.out.println("=======");
test(TypeTest.class.getDeclaredField("it"));
System.out.println("=======");
test(TypeTest.class.getDeclaredField("iarray"));
System.out.println("=======");
test(TypeTest.class.getDeclaredField("list"));
System.out.println("=======");
test(TypeTest.class.getDeclaredField("slist"));
System.out.println("=======");
test(TypeTest.class.getDeclaredField("tlist"));
System.out.println("=======");
test(TypeTest.class.getDeclaredField("t"));
System.out.println("=======");
test(TypeTest.class.getDeclaredField("tarray"));
}
public static void test(Field field) {
if (field.getType().isPrimitive()) {
System.out.println(field.getName() + "是基本数据类型");
} else {
System.out.println(field.getName() + "不是基本数据类型");
}
if (field.getGenericType() instanceof ParameterizedType) {
System.out.println(field.getName() + "是泛型类型");
} else {
System.out.println(field.getName() + "不是泛型类型");
}
if (field.getType().isArray()) {
System.out.println(field.getName() + "是普通数组");
} else {
System.out.println(field.getName() + "不是普通数组");
}
if (field.getGenericType() instanceof GenericArrayType) {
System.out.println(field.getName() + "是泛型数组");
} else {
System.out.println(field.getName() + "不是泛型数组");
}
if (field.getGenericType() instanceof TypeVariable) {
System.out.println(field.getName() + "是泛型变量");
} else {
System.out.println(field.getName() + "不是泛型变量");
}
}
}
QualifierAnnotationAutowireCandidateResolver
org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver#isAutowireCandidate
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
//先执行上层判断,上层是GenericTypeAwareAutowireCandidateResolver,泛型的判断
boolean match = super.isAutowireCandidate(bdHolder, descriptor);
if (match) {
//先拿到参数级别@Qualifier注解进行校验
//descriptor.getAnnotations()拿的是参数级别的注解
match = checkQualifiers(bdHolder, descriptor.getAnnotations());
if (match) {
MethodParameter methodParam = descriptor.getMethodParameter();
if (methodParam != null) {
//再拿方法级别的@Qualifier注解进行校验
Method method = methodParam.getMethod();
if (method == null || void.class == method.getReturnType()) {
//methodParam.getMethodAnnotations()拿到的是方法上的注解
match = checkQualifiers(bdHolder, methodParam.getMethodAnnotations());
}
}
}
}
return match;
}
当前注入点上有Qualifier注解的话,会判断候选Bean中是否也写了Qualifier注解,然后进行值匹配,checkQualifiers就不看了,介绍一下应用场景:
定义两个注解:
@Target({ElementType.TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier("random")//@Random上标注了@Qualifier
public @interface Random {
}
@Target({ElementType.TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier("roundRobin")//@RoundRobin上标注了@Qualifier
public @interface RoundRobin {
}
定义一个接口和两个实现类,表示负载均衡:
public interface LoadBalance {
String select();
}
@Component
@Random
public class RandomStrategy implements LoadBalance {
@Override
public String select() {
return null;
}
}
@Component
@RoundRobin
public class RoundRobinStrategy implements LoadBalance {
@Override
public String select() {
return null;
}
}
使用:
@Component
public class UserService {
@Autowired
@RoundRobin//使用注解就能切换实现
private LoadBalance loadBalance;
public void test() {
System.out.println(loadBalance);
}
}
5. 添加到结果集
org.springframework.beans.factory.support.DefaultListableBeanFactory#addCandidateEntry
//向候选映射添加一个条目:如果可用,则添加一个bean实例,或者仅添加已解析的类型,
//从而防止在主候选选择之前提前进行bean初始化。
private void addCandidateEntry(Map<String, Object> candidates, String candidateName,
DependencyDescriptor descriptor, Class<?> requiredType) {
//具有嵌套元素的多元素声明的依赖描述符。
if (descriptor instanceof MultiElementDescriptor) {
//结果集放入的是Bean实例
Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
if (!(beanInstance instanceof NullBean)) {
candidates.put(candidateName, beanInstance);
}
}
else if (containsSingleton(candidateName) || (descriptor instanceof StreamDependencyDescriptor &&
((StreamDependencyDescriptor) descriptor).isOrdered())) {
//如果单例池中存在
//或者是StreamDependencyDescriptor:用于流访问多个元素的依赖描述符标记。
//直接放入Bean对象
Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
candidates.put(candidateName, (beanInstance instanceof NullBean ? null : beanInstance));
}
else {
//将匹配到beanName以及beanClass存入
candidates.put(candidateName, getType(candidateName));
}
}
放入Bean对象的情况:
org.springframework.beans.factory.config.DependencyDescriptor#resolveCandidate
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
throws BeansException {
return beanFactory.getBean(beanName);
}
放入Bean Class的情况:
org.springframework.beans.factory.support.AbstractBeanFactory#getType(java.lang.String)
public Class<?> getType(String name) throws NoSuchBeanDefinitionException {
return getType(name, true);
}
public Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException {
String beanName = transformedBeanName(name);
// Check manually registered singletons.
// 检查手动注册的单例
//如果有实例,根据实例获取Class类型
Object beanInstance = getSingleton(beanName, false);
if (beanInstance != null && beanInstance.getClass() != NullBean.class) {
//FactoryBean,常规引用的情况
if (beanInstance instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
return getTypeForFactoryBean((FactoryBean<?>) beanInstance);
}
else {
//普通Bean、FactoryBean引用的情况...
return beanInstance.getClass();
}
}
//检查BeanDefinition,当前工厂不存在,委托父类工厂处理
// No singleton instance found -> check bean definition.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// No bean definition found in this factory -> delegate to parent.
return parentBeanFactory.getType(originalBeanName(name));
}
//根据BeanDefinition获取Class类型
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// Check decorated bean definition, if any: We assume it'll be easier
// to determine the decorated bean's type than the proxy's type.
// 检查修饰的bean定义(如果有):我们假设确定修饰的beam的类型比确定代理的类型更容易。
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
if (dbd != null && !BeanFactoryUtils.isFactoryDereference(name)) {
RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd);
Class<?> targetClass = predictBeanType(dbd.getBeanName(), tbd);
if (targetClass != null && !FactoryBean.class.isAssignableFrom(targetClass)) {
return targetClass;
}
}
//推测Bean Class类型,见1.2.c
Class<?> beanClass = predictBeanType(beanName, mbd);
// 处理FactoryBean情况
// Check bean class whether we're dealing with a FactoryBean.
if (beanClass != null && FactoryBean.class.isAssignableFrom(beanClass)) {
if (!BeanFactoryUtils.isFactoryDereference(name)) {
// If it's a FactoryBean, we want to look at what it creates, not at the factory class.
return getTypeForFactoryBean(beanName, mbd, allowFactoryBeanInit).resolve();
}
else {
return beanClass;
}
}
//普通Bean情况
else {
return (!BeanFactoryUtils.isFactoryDereference(name) ? beanClass : null);
}
}
6. 回退匹配
搜了一下调用点,在GenericTypeAwareAutowireCandidateResolver中,泛型处理的时候:
回退匹配允许不可解析的泛型,例如纯HashMap-to-Map<String,String>;
实际上也可以将java.util.Properties映射到任何Map(因为尽管形式上是Map<Object,Object>,java.util.Properties通常被视为Map<String,String>)。