我们再来到 doResolveDependency
方法
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor); try { // 如果 DependencyDescriptor 是一个 ShortcutDependencyDescriptor // 那么会直接理解 beanName 从 beanFactory 中拿到一个 bean // 在利用 @Autowired 注解来进行依赖注入时会利用 ShortcutDependencyDescriptor 来进行依赖注入的缓存 // 表示当解析完成某个依赖信息后,会把依赖的 bean 的 beanName 缓存起来 Object shortcut = descriptor.resolveShortcut(this); if (shortcut != null) { return shortcut; } // 获取 descriptor 的具体赖姓 Class<?> type = descriptor.getDependencyType(); // 1. 获取 @Value 注解中所配置的值 Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor); //判断是否通过 @Value 指定了 if (value != null) { if (value instanceof String) { // 先进行占位符的填充,解析 "$" 符号 String strVal = resolveEmbeddedValue((String) value); BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null); // 解析 Spring EL 表达式, 解析 "#" 符号(可以是运算,也可以是某个 bean 的名字) value = evaluateBeanDefinitionString(strVal, bd); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); try { return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor()); } catch (UnsupportedOperationException ex) { // A custom TypeConverter which does not support TypeDescriptor resolution... return (descriptor.getField() != null ? converter.convertIfNecessary(value, type, descriptor.getField()) : converter.convertIfNecessary(value, type, descriptor.getMethodParameter())); } } //没有使用 @Value 注解 //2. 要注入的类型不是一个 Map,Array, Collection Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter); if (multipleBeans != null) { return multipleBeans; } //通过 Type 查找,可能找到多个, 这里的 value ,可能是具体的实例对象, 也能暂时只是 Class 对象 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; // 根据 type 查找到了多个 if (matchingBeans.size() > 1) { // 如果找到了多个,去尝试确定出唯一的一个 autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor); if (autowiredBeanName == null) { if (isRequired(descriptor) || !indicatesMultipleBeans(type)) { //如果找到多个,并且依赖是 required , 或者不是数组或者 Collection 或者 Map 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) { // 调用 beanFactory.getbean() 创建 bean 对象 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; } finally { ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint); } }
上面有我们的常用注入 @Value
, @Autowired
的处理,当我们同一个类型的 Bean 查找到多个结果的时候,我们来看如何选择的 determineAutowireCandidate
方法的实现。
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) { Class<?> requiredType = descriptor.getDependencyType(); // 取 @Primary 的 bean String primaryCandidate = determinePrimaryCandidate(candidates, requiredType); if (primaryCandidate != null) { return primaryCandidate; } // 取优先级最高的 Bean 通过 @Priority 来定义优先级,数字越小,优先级越高 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(); if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) || // 根据属性名确定 matchesBeanName(candidateName, descriptor.getDependencyName())) { return candidateName; } } return null; }
doResolveDependency 总结
(1) 首先调用 DefaultListableBeanFactory#doResolveDependency
方法中通过属性来获取对应的需要注入的 Bean 。
(2) 第一步解析 @Value
注解, 如果存在就解析 el 表达式获取 Bean 。
(3) 第二步解析 @Autowired
自动注入注解,如果存在首先就去解析这个注解。
(4) 通过依赖的类型去查找所有符合条件的候选 Bean。
(5) 当符合条件的 Bean 的个数为 0 的时候,判断 @Autowired
的 required 属性是否为 true, 如果是 true 那么就抛异常,提示找不到 Bean。
(6) 如果匹配到1个的时候,我们就直接使用。
(7) 如果匹配到多个的时候, 我们就需要做一下的选择:
首先遍历所有的候选 beanName, 判断是否有 @Primary
注解,如果有一个就返回,如果有多个会抛出异常 NoUniqueBeanDefinitionException
;
然后,遍历所有的候选 beanName, 判断是否有 @Priority
注解,如果有就按照自然顺序排序返回第一个,如果存在多个 Bean 优先级相同则抛出异常 NoUniqueBeanDefinitionException
( 注意:这里容易混淆 @Order
注解);
最后,遍历所有的候选 beanName,如果上述两种情况都不能选择到匹配的,那么将读取参数名通过 byName 的方式来匹配 Bean。
(8) 把所有的字段和需要注入的到 Bean 的属性之后完成属性的注入。
(9) 最后,若存在属性pvs,那就做赋值操作
applyPropertyValues
该方法主要是实现 pvs 的值的运用
(1) 检测属性值列表是否已转换过的,若转换过,则直接填充属性,无需再次转换
(2) 遍历属性值列表 pvs,解析原始值 originalValue,得到解析值 resolvedValue
(3) 对解析后的属性值 resolvedValue 进行类型转换
(4) 将类型转换后的属性值设置到 PropertyValue 对象中,并将 PropertyValue 对象存入 deepCopy 集合中将 deepCopy 中的属性信息注入到 bean 对象中
// 本方法传入了beanName和bean定义信息,以及它对应的BeanWrapper和value值 protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { if (pvs.isEmpty()) { return; } if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) { ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext()); } MutablePropertyValues mpvs = null; List<PropertyValue> original; // 判断是否是 类型 MutablePropertyValues if (pvs instanceof MutablePropertyValues) { mpvs = (MutablePropertyValues) pvs; // 若该mpvs中的所有属性值都已经转换为对应的类型,则把mpvs设置到BeanWrapper中,返回 if (mpvs.isConverted()) { // Shortcut: use the pre-converted values as-is. try { bw.setPropertyValues(mpvs); return; } catch (BeansException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Error setting property values", ex); } } // 否则,拿到里面的属性值 original = mpvs.getPropertyValueList(); } else { original = Arrays.asList(pvs.getPropertyValues()); } // 若调用者没有自定义转换器,那就使用BeanWrapper本身(因为BeanWrapper实现了TypeConverter 接口) TypeConverter converter = getCustomTypeConverter(); if (converter == null) { converter = bw; } // 获取BeanDefinitionValueResolver,该Bean用于将bean定义对象中包含的值解析为应用于目标bean实例的实际值。 BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter); // Create a deep copy, resolving any references for values. List<PropertyValue> deepCopy = new ArrayList<>(original.size()); boolean resolveNecessary = false; // 遍历没有被解析的original属性值 for (PropertyValue pv : original) { if (pv.isConverted()) { deepCopy.add(pv); } else {// 被解析过的PropertyValue此处会一步步解析 String propertyName = pv.getName(); Object originalValue = pv.getValue(); // 解析各式各样的值 Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue); Object convertedValue = resolvedValue; // 属性可写 并且 不是嵌套(如foo.bar,java中用getFoo().getBar()表示)或者索引(如person.addresses[0])属性 boolean convertible = bw.isWritableProperty(propertyName) && !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName); if (convertible) { // 用类型转换器进行转换 convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter); } // Possibly store converted value in merged bean definition, // in order to avoid re-conversion for every created bean instance. if (resolvedValue == originalValue) { if (convertible) { pv.setConvertedValue(convertedValue); } deepCopy.add(pv); } else if (convertible && originalValue instanceof TypedStringValue && !((TypedStringValue) originalValue).isDynamic() && !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) { pv.setConvertedValue(convertedValue); deepCopy.add(pv); } else { resolveNecessary = true; deepCopy.add(new PropertyValue(pv, convertedValue)); } } } // 标记mpvs已经转换 if (mpvs != null && !resolveNecessary) { mpvs.setConverted(); } // Set our (possibly massaged) deep copy. // 使用转换后的值进行填充 try { // 对属性的值进行注入 bw.setPropertyValues(new MutablePropertyValues(deepCopy)); } catch (BeansException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Error setting property values", ex); } }