Spring对BeanFactory底层的最终实现是DefaultListableBeanFactory,DefaultListableBeanFactory对resolveDependency方法实现的源码如下。
/**
* @param descriptor 字段或方法的依赖描述信息
* @param requestingBeanName 需要注入依赖的 bean 的名称
* @param autowiredBeanNames 需要注入的依赖的 bean 名称的集合,解析的结果会存放该集合中
* @param typeConverter 类型转换
* @return
* @throws BeansException
*/
@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (Optional.class == descriptor.getDependencyType()) {
// 解析 Optional 依赖
return createOptionalDependency(descriptor, requestingBeanName);
} else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
// 解析 ObjectFactory 或 ObjectProvider 依赖
return new DependencyObjectProvider(descriptor, requestingBeanName);
} else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
// 解析 javax.inject.Provider 注解标注的依赖
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
} else {
// 懒加载的对象返回代理对象
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
// 其他对象进行解析
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
解析依赖的方法,根据不同的依赖类型使用不同的解析方式。对于Optional、ObjectFactory、ObjectProvider依赖类型,由于需要解析的是其泛型的实际类型,因此Spring会将依赖描述信息重新包装为另一个DependencyDescriptor ,然后再解析。而Java规范JSR-330中注解javax.inject.Provider的处理则只是将实现委托给另一个类处理。对于不同类型的依赖解析,最终都会调用doResolveDependency方法。以Optional类型的解析方法createOptionalDependency为例源码如下
private Optional> createOptionalDependency(
DependencyDescriptor descriptor, @Nullable String beanName, final Object... args) {
// 包装依赖描述信息,解析依赖的类型时会将嵌套层次加1
// 例如原来要解析的类型是 Optional 的原始类型,嵌套层次加1后会解析泛型类型的实际类型 T
DependencyDescriptor descriptorToUse = new NestedDependencyDescriptor(descriptor) {
@Override
public boolean isRequired() {
return false;
}
@Override
public Object resolveCandidate(String beanName, Class> requiredType, BeanFactory beanFactory) {
return (!ObjectUtils.isEmpty(args) ? beanFactory.getBean(beanName, args) :
super.resolveCandidate(beanName, requiredType, beanFactory));
}
};
// 然后真正解析依赖
Object result = doResolveDependency(descriptorToUse, beanName, null, null);
// 再将解析出的依赖包装到 Optional 中
return (result instanceof Optional ? (Optional>) result : Optional.ofNullable(result));
}
进入doResolveDependency方法
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
... 省略部分代码
// 快捷解析依赖
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
Class> type = descriptor.getDependencyType();
// 先根据 @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());
try {
// 将结果进行类型转换
return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
} catch (UnsupportedOperationException ex) {
... 省略部分代码
}
}
// 尝试解析包含多个 bean 的依赖对象
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
// 查找所需类型的依赖
Map matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
// 依赖不存在,抛出异常
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
if (matchingBeans.size() > 1) {
// 存在多个类型相同的依赖,确定使用哪个依赖
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), 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;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
} else {
// 只查到一个依赖
// We have exactly one match.
Map.Entry entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
if (result instanceof NullBean) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
return result;
}
对于集合类型以及单一类型,最终都会调用findAutowireCandidates方法查找自动装配的候选对象,对于集合类型会把查找到的候选对象包装为对应所需的类型,对于单一类型则需要确认最终使用哪个依赖。进入findAutowireCandidates方法
protected Map findAutowireCandidates(
@Nullable String beanName, Class> requiredType, DependencyDescriptor descriptor) {
// 查找 Spring 中给定类型的 bean 名称
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map result = new LinkedHashMap<>(candidateNames.length);
// 先解析 Spring 中游离的对象,如果类型和所需类型匹配则加入到结果中
for (Map.Entry, 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;
}
}
}
// 然后解析 Spring 中注册 BeanDefinition 中的名称
for (String candidate : candidateNames) {
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
// 依赖非 bean 自身,并且 bean 可以作为候选项,加入到结果中
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
... 省略回退处理代码,和上述候选名称循环类似
return result;
}
候选对象的获取主要有两个来源,一个是游离对象,一个是Spring中的bean,Spring 根据类型获取到对应的实例后添加到返回结果。这也印证了前面文章所说的依赖注入的依赖来源。需要留意的是对isAutowireCandidate方法的调用,isAutowireCandidate方法用于判断一个一个对象是否可以作为候选项,其内部出了判断bean定义中是否可以作为候选项的标识,还会判断泛型、@Qualifier 等。对于单一类型的依赖解析,如果查找到了多个bean,则需要判断到底使用哪一个bean作为结果,进入determineAutowireCandidate方法
protected String determineAutowireCandidate(Map candidates, DependencyDescriptor descriptor) {
Class> requiredType = descriptor.getDependencyType();
// 先根据 primary 判断
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
if (primaryCandidate != null) {
return primaryCandidate;
}
// primary 不存在,则根据优先级判断
String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
if (priorityCandidate != null) {
return priorityCandidate;
}
// Fallback
for (Map.Entry entry : candidates.entrySet()) {
String candidateName = entry.getKey();
Object beanInstance = entry.getValue();
// 依赖为游离对象或指定依赖的 bean 名称匹配,直接返回
if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
matchesBeanName(candidateName, descriptor.getDependencyName())) {
return candidateName;
}
}
return null;
}
这里优先选择标记 primary 为 true 的 bean,如果都没有标注则会选择一个优先级最高的 bean,如果存在多个优先级相同的 bean 会抛出异常。最后会将游离对象或和依赖的名称匹配的 bean 作为结果进行返回。
总结
Spring 依赖解析会优先根据 @Value 注解进行解析,并且支持多种类型。对于类型为 Optional、ObjectFactory 的依赖 Spring 会将依赖包装后返回,其他类型又分为集合类型和单一类型,对于集合类型 Spring 查找对所有依赖后直接包装为对应的类型返回即可,对于单一类型 Spring 会优先考虑 primary、最高优先级、和所需 bean 名称匹配的 bean。