概述
Spring依赖查找
上篇文章依赖处理过程我们通过简单分析了解到了spring处理依赖时的过程,而其中里面有一个方法 resolveDependency() 就是依赖查找过程。而今天我们主要深入去探讨一下这个方法以及相关的实现
resolveDependency()方法
我们发现,resolveDependency() 方法实现在DefaultListableBeanFactory 这个类里,也就是我们底层IOC容器BeanFactory的实现类
@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
// 按照惯例不是本文相关代码我们先不关注
// 这里是获得需要延迟加载(懒加载)的代理对象
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
// 如果获取结果为空,则说明不是懒加载,进入 doResolveDependency() 方法
if (result == null) {
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
// 若不为空,则说明该依赖是需要延迟处理的依赖,此时直接返回他的代理对象
return result;
}
在resolveDependency 里,首先先判断该bean是否需要延迟处理,如果是的话,就直接返回该bean的代理对象,否则则进入doResolveDependency() 方法
@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
/*
* 如果该bean是集合类型的bean,这里会进行查找,找到后就直接返回,返回null说明
* 该bean不是集合类型的bean,进入下面的逻辑
*/
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
// 当走到这里的时候,说明该bean不是集合类型的bean,因此再次进行依赖查找
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
// 如果该map为空则说明没找到相关bean,返回null
if (matchingBeans.isEmpty()) {
return null;
}
String autowiredBeanName;
Object instanceCandidate;
// 如果 map 的 size() 大于 1, 则说明找到两个个以上的bean
if (matchingBeans.size() > 1) {
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
// We have exactly one match.
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
// 将该beanName加入数组
autowiredBeanNames.add(autowiredBeanName);
// 获得bean对象,底层是通过beanFactory.getBean()来获取(如果是Class类型的前提下)
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
// 返回获取得到的bean
return result;
}
接下来我们慢慢分析这段代码
首先进入resolveMultipleBeans() 方法该方法主要是获取集合类型的bean,若该bean不是集合类型,则返回null
@Nullable
private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {
final Class<?> type = descriptor.getDependencyType();
// 如果是stream流
if (descriptor instanceof StreamDependencyDescriptor) {...}
// 如果是数组
else if (type.isArray()) {...}
// 如果是其他集合
else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {...}
// 如果是map
else if (Map.class == type) {...}
else {return null;}
}
以上是对该方法的一些简单分析,其中在每个判断都会调用findAutowireCandidates() 方法。该方法我们将会在下文继续分析
resolveMultipleBeans() 方法后,若该bean不是集合类型bean,则进入下面的逻辑,也就是下面的
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
而这个方法正是我们刚刚所提到的方法
protected Map<String, Object> findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
Class<?> autowiringType = classObjectEntry.getKey();
if (autowiringType.isAssignableFrom(requiredType)) {
Object autowiringValue = classObjectEntry.getValue();
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
if (requiredType.isInstance(autowiringValue)) {
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
for (String candidate : candidateNames) {
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
return result;
}
这段代码的大意是,先查找出所有满足的beanName,然后循环这个Names数组,将其一一加入到result返回
得到result后,继续对matchingBeans做判断
如果该map大于1,则说明存在两个以上满足条件的bean,因此进入determineAutowireCandidate() 方法
@Nullable
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
if (primaryCandidate != null) {
return primaryCandidate;
}
return null;
}
这里简单来看的话,就是去查找bean为primary的beanName,然后将其返回,其底层实际上是去BeanDefinition里找primary属性
获取到该Bean的名称后,然后再通过beanFactory.getBean() 来获取bean
instanceCandidate = matchingBeans.get(autowiredBeanName);
// 如果instanceCandidate为Class类型才会执行这个,这里也失去通过beanFactory.getBean()来获取bean
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
最终就得到这个bean实体了
总结
依赖处理可以分为以下几个步骤:
- 第一步:判断是否是延迟加载,是则返回代理对象
- 第二步:判断是否是集合类型bean,是则返回该集合类型的bean
- 第三步:将找到所有符合条件的bean加入到map
- 第四步:对该map做判断:如果map的大小大于1,则去找有primary属性的bean;
- 第五步:获取到bean,然后返回
最后
以上就是粗心飞鸟为你收集整理的spring依赖查找过程Spring依赖查找resolveDependency()方法总结的全部内容,希望文章能够帮你解决spring依赖查找过程Spring依赖查找resolveDependency()方法总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复