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<String> 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<T> 的原始类型,嵌套档次加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<String> 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<String, Object> 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<String, Object> 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<String, Object> findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
// 查找 Spring 中给定类型的 bean 名称
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
// 先解析 Spring 中游离的对象,如果类型和所需类型匹配则退出到后果中
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;
}
}
}
// 而后解析 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<String, Object> 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<String, Object> 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。
发表回复