前文

源码解析

入参说明

  • includeNonSingletons:是否包括非单例的 bean,比如 prototype scope
  • allowEagerInit:为了这个检查(找出所有匹配类型的 beanName),是否初始化 lazy-init 单例和由 FactoryBeans 创建的对象。此处我们传入的值为 true。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

public static String[] beanNamesForTypeIncludingAncestors(
ListableBeanFactory lbf, Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {

Assert.notNull(lbf, "ListableBeanFactory must not be null");
//方法主干还是在这行 getBeanNamesForType
String[] result = lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
//下面的内容就是从 bf 的 parent 中找,
if (lbf instanceof HierarchicalBeanFactory) {
HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;
if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
//此处以 parent 再来调此方法,合并结果。
String[] parentResult = beanNamesForTypeIncludingAncestors(
(ListableBeanFactory) hbf.getParentBeanFactory(), type, includeNonSingletons, allowEagerInit);
List<String> resultList = new ArrayList<String>();
resultList.addAll(Arrays.asList(result));
for (String beanName : parentResult) {
if (!resultList.contains(beanName) && !hbf.containsLocalBean(beanName)) {
resultList.add(beanName);
}
}
result = StringUtils.toStringArray(resultList);
}
}
return result;
}

看来我们还需要继续深入到 getBeanNamesForType中去一探究竟。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
//configurationFrozen:判断所有 bean 的 定义元数据是否可以被缓存
//如果不能缓存 或没type 或不允许急切初始化,则直接查 doGetBeanNamesForType
if (!isConfigurationFrozen() || type == null || !allowEagerInit) {
return doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit);
}
//否则先查缓存,没有缓存的话再查 doGetBeanNamesForType 并塞入缓存
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);
//判断是否缓存安全:依据我们目标class 和当前beanFactory的classLoader是否一致
if (ClassUtils.isCacheSafe(type, getBeanClassLoader())) {
cache.put(type, resolvedBeanNames);
}
return resolvedBeanNames;
}

再深入一层到 doGetBeanNamesForType ,其中逻辑外层是遍历所有的 beanName, 对于不是别名的进行处理,处理过程如下(省略了 try-catch ):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//首先获取这个beanName对应的mbd,它的相关定义配置信息
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// Only check bean definition if it is complete.
// 不是抽象的
// 并且 允许急切初始化 或 (此bean不需要急切初始化 且(有beanClass 或 不是lazyInit 或 允许急切的类加载,即使是懒惰的初始化bean))
if (!mbd.isAbstract() && (allowEagerInit ||
((mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading())) &&
!requiresEagerInitForType(mbd.getFactoryBeanName()))) {
// In case of FactoryBean, match object created by FactoryBean.
//判断是否 FactoryBean
boolean isFactoryBean = isFactoryBean(beanName, mbd);
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
//接下来又是一段非常长的逻辑判断,判断是否匹配
boolean matchFound =
(allowEagerInit || !isFactoryBean ||
(dbd != null && !mbd.isLazyInit()) || containsSingleton(beanName)) &&
(includeNonSingletons ||
(dbd != null ? mbd.isSingleton() : isSingleton(beanName))) &&
isTypeMatch(beanName, type);
if (!matchFound && isFactoryBean) {
// In case of FactoryBean, try to match FactoryBean instance itself next.
//如果不匹配,还要试试匹配FactoryBean本身,因为说不好要的就是这个FactoryBean呢
beanName = FACTORY_BEAN_PREFIX + beanName;
matchFound = (includeNonSingletons || mbd.isSingleton()) && isTypeMatch(beanName, type);
}
if (matchFound) {
result.add(beanName);
}
}

//检查一遍手动的单例集合
//对于 FactoryBean ,如果匹配到它的getObject()满足,就不会继续去匹配它本身
for (String beanName : this.manualSingletonNames) {
// In case of FactoryBean, match object created by FactoryBean.
if (isFactoryBean(beanName)) {
if ((includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type)) {
result.add(beanName);
// Match found for this bean: do not match FactoryBean itself anymore.
continue;
}
// In case of FactoryBean, try to match FactoryBean itself next.
beanName = FACTORY_BEAN_PREFIX + beanName;
}
// Match raw bean instance (might be raw FactoryBean).
if (isTypeMatch(beanName, type)) {
result.add(beanName);
}
}

}

前一段的超长的逻辑判断看得人头疼,但是先看下半段的遍历,突然就找到了最关键判断类型匹配的函数 isTypeMatch,从名字就看出来,这应该就是判断类型匹配的地方啦。

然而点进去一看,居然是长达 100 行的函数。

isTypeMatch

首先从单例中查找,匹配这个单例 bean 的类型和我们目标的类型,其中对 factoryBean 的处理也比较简单,就不再贴代码了。对于注册的 null instance ,也返回 false。

再从父工厂找,递归 isTypeMatch 。

再就是复杂的查找了。

先定义个 typesToMatch ,包括了目标类型和 FactoryBean .

然后我们再继续看代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// 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 的装饰definition。
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
if (dbd != null && !BeanFactoryUtils.isFactoryDereference(name)) {
RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd);
Class<?> targetClass = predictBeanType(dbd.getBeanName(), tbd, typesToMatch);
if (targetClass != null && !FactoryBean.class.isAssignableFrom(targetClass)) {
return typeToMatch.isAssignableFrom(targetClass);
}
}
// 注意此处predictBeanType返回了很关键的Class ,我们后面再详细分析此方法。
Class<?> beanType = predictBeanType(beanName, mbd, typesToMatch);
if (beanType == null) {
return false;
}

// Check bean class whether we're dealing with a FactoryBean.
//接下来就是处理 FactoryBean
if (FactoryBean.class.isAssignableFrom(beanType)) {
if (!BeanFactoryUtils.isFactoryDereference(name)) {
// If it's a FactoryBean, we want to look at what it creates, not the factory class.
beanType = getTypeForFactoryBean(beanName, mbd);
if (beanType == null) {
return false;
}
}
}
else if (BeanFactoryUtils.isFactoryDereference(name)) {
// 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.
beanType = predictBeanType(beanName, mbd, FactoryBean.class);
if (beanType == null || !FactoryBean.class.isAssignableFrom(beanType)) {
return false;
}
}
//对其 resolvableType 进行处理
ResolvableType resolvableType = mbd.targetType;
if (resolvableType == null) {
resolvableType = mbd.factoryMethodReturnType;
}
if (resolvableType != null && resolvableType.resolve() == beanType) {
return typeToMatch.isAssignableFrom(resolvableType);
}
//如果以上都没有处理掉的话, 则判读typeToMatch和 beanType
return typeToMatch.isAssignableFrom(beanType);

总结:

目前很遗憾 isTypeMatch 往下还有很复杂的逻辑暂时不能看懂,但是从外层的逻辑大致知道寻找所有匹配的beanName 的方法非常的“复杂粗暴”。遍历 beanDefinitionNames 已定义的所有 bean,即使是一个小型的项目也有近200个 bean 需要遍历,并且这数百个 beanName 还要遍历非常多次。

只能说根据 type 寻找 bean 实在是比根据 name 复杂了太多太多,从源码看真是深坑,理解了为什么作者直接忽略了这部分…应该是第二遍或第三遍阅读 Spring 源码时才能理解。