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。