前面说到Spring 通过bytype注入,留下了一些没有诉说,现在来详细看看
protected void autowireByType( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { TypeConverter converter = getCustomTypeConverter(); if (converter == null) { converter = bw; } Set<String> autowiredBeanNames = new LinkedHashSet<>(4); // 找到有对应set方法的属性 String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { try { PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName); // Don't try autowiring by type for type Object: never makes sense, // even if it technically is a unsatisfied, non-simple property. //这里是判断是你的属性描述器,也就是说你的set方法的参数的类型不能是Object //因为如果setUserService(Object userService),那么像这个方法,如果是Object,spring根本不知道你要注入那个bean //所以不能是Object if (Object.class != pd.getPropertyType()) { // set方法中的参数信息 //根据属性描述器获取这个set方法的参数信息 MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); // Do not allow eager init for type matching in case of a prioritized post-processor. boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered); /** * * 根据方法的参数MethodParameter获取一个bean * 到这里知道这个方法是byType,byType的原理是根据你的set方法的参数类型得到一个bean,所以这里是通过 * set方法的参数比如setUserService(UserService uservice)中的UserService来构建一个依赖描述器 * 这个依赖描述器得到过后,根据这个依赖描述器和其他一些参数得到一个bean */ DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager); // 根据类型找bean,这就是byType //简单来说就是根据依赖描述器通过下面这个方法得到一个Bean,然后注入到pvs中 //后面说 Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter); if (autowiredArgument != null) { pvs.add(propertyName, autowiredArgument); } for (String autowiredBeanName : autowiredBeanNames) { registerDependentBean(autowiredBeanName, beanName); if (logger.isTraceEnabled()) { logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" + propertyName + "' to bean named '" + autowiredBeanName + "'"); } } autowiredBeanNames.clear(); } } catch (BeansException ex) { throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex); } } } 找到有对应set方法的属性 String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) { Set<String> result = new TreeSet<>(); PropertyValues pvs = mbd.getPropertyValues(); // 在BeanDefinition中添加的属性和值, // PropertyDescriptor[] pds = bw.getPropertyDescriptors(); // 对类里所有的属性进行过滤,确定哪些属性是需要进行自动装配的 for (PropertyDescriptor pd : pds) { // 属性有set方法,并且 // 没有通过DependencyCheck排除,并且 // 没有在BeanDefinition中给该属性赋值,并且 // 属性的类型不是简单类型 if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) && !BeanUtils.isSimpleProperty(pd.getPropertyType())) { result.add(pd.getName()); } } // 返回过滤之后的结果,后续只对这些属性进行自动装配 return StringUtils.toStringArray(result); } 得到属性描述getPropertyDescriptor,根据属性描述器获取这个set方法的参数信息getWriteMethodParameter,然后根据方法的参数MethodParameter构建一个依赖描述器通过AutowireByTypeDependencyDescriptor根据依赖描述器得到一个Bean通过resolveDependency public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { // DependencyDescriptor表示一个依赖,可以是一个属性字段,可能是一个构造方法参数,可能是一个set方法参数 // 根据descriptor去BeanFactory中找到bean descriptor.initParameterNameDiscovery(getParameterNameDiscoverer()); // 如果依赖的类型是Optional if (Optional.class == descriptor.getDependencyType()) { return createOptionalDependency(descriptor, requestingBeanName); } else if (ObjectFactory.class == descriptor.getDependencyType() || ObjectProvider.class == descriptor.getDependencyType()) { return new DependencyObjectProvider(descriptor, requestingBeanName); } else if (javaxInjectProviderClass == descriptor.getDependencyType()) { return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName); } else { Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary( descriptor, requestingBeanName); if (result == null) { // 通过解析descriptor找到bean对象 result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); } return result; } } 判断descriptor.getDependencyType()的类型若果依赖描述上存在@Lazy注解,那么会生成一个代理对象,然后返回包装成Optional否则调用doResolveDependen通过解析依赖描述找到bean对象result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter)
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具体的类型,某个Filed的类型或某个方法参数的类型 Class<?> type = descriptor.getDependencyType(); // 获取@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 { // 把value从descriptor.getTypeDescriptor()类型转化为type类 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注解 // 要注入的依赖的类型是不是一个Map、Array、Collection Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter); if (multipleBeans != null) { return multipleBeans; } // 通过type找,可能找到多个 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)) { 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(beanName);创建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); } } 先判断是不是Shortcut,如果是那么可以理解beanName直接从beanFactory中拿到一个bean // 如果DependencyDescriptor是一个ShortcutDependencyDescriptor, // 那么会直接理解beanName从beanFactory中拿到一个bean, // 在利用@Autowired注解来进行依赖注入时会利用ShortcutDependencyDescriptor来进行依赖注入的缓存, // 表示当解析完某个依赖信息后,会把依赖的bean的beanName缓存起来 Object shortcut = descriptor.resolveShortcut(this); if (shortcut != null) { return shortcut; } //------------------------------------------------------------------------------ @Override public Object resolveShortcut(BeanFactory beanFactory) { return beanFactory.getBean(this.shortcut, this.requiredType); } 判断@Value注解是否存在,如果存在获取并解析descriptor上的@Value注解,并进行解析返回 // 获取@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 { // 把value从descriptor.getTypeDescriptor()类型转化为type类 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())); } } 若果没有则判断descriptor的类型descriptor的类型为Collection,或者map则直接返回map的value或者map // 没有使用@Value注解 // 要注入的依赖的类型是不是一个Map、Array、Collection Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter); if (multipleBeans != null) { return multipleBeans; } 调用findAutowireCandidates(beanName, type, descriptor),该方法返回一个Map,表示会根据type去找bean,Map的key为beanName,Map的value为对象(注意可能是bena的对象,也可能是某个bean的class对象,因为该方法只负责根据类型找到对应的bean,如果该bean还没有实例化,那么该方法不负责去实例化,只返回该bean对应的Class对象,表示这个bean也是结果之一) // 根据requiredType寻找自动匹配的候选者bean protected Map<String, Object> findAutowireCandidates( @Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) { // 根据requiredType找到candidateNames,表示根据type找到了候选beanNames // Ancestors是祖先的意思,所以这个方法是去当前beanfactory以及祖先beanfactory中去找类型为requiredType的bean的名字 String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this, requiredType, true, descriptor.isEager()); Map<String, Object> result = new LinkedHashMap<>(candidateNames.length); // 先从resolvableDependencies for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) { Class<?> autowiringType = classObjectEntry.getKey(); // requiredType是autowiringType的子类 // 也就是,某个bean中的属性的类型是requiredType,是resolvableDependencies中的子类 if (autowiringType.isAssignableFrom(requiredType)) { // 是resolvableDependencies中的子类所存的对象 Object autowiringValue = classObjectEntry.getValue(); autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType); if (requiredType.isInstance(autowiringValue)) { // 把resolvableDependencies中保存的对象作为当前属性的一个候选者 result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue); break; } } } // 对候选bean进行过滤,首先候选者不是自己,然后候选者是支持自动注入给其他bean的 for (String candidate : candidateNames) { // isAutowireCandidate方法中会去判断候选者是否和descriptor匹配 if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) { addCandidateEntry(result, candidate, descriptor, requiredType); } } if (result.isEmpty()) { boolean multiple = indicatesMultipleBeans(requiredType); // Consider fallback matches if the first pass failed to find anything... DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch(); for (String candidate : candidateNames) { if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) && (!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) { addCandidateEntry(result, candidate, descriptor, requiredType); } } if (result.isEmpty() && !multiple) { // Consider self references as a final pass... // but in the case of a dependency collection, not the very same bean itself. for (String candidate : candidateNames) { if (isSelfReference(beanName, candidate) && (!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) && isAutowireCandidate(candidate, fallbackDescriptor)) { addCandidateEntry(result, candidate, descriptor, requiredType); } } } } return result; } 判断根据type有没有找到bean如果没有找到,判断是不是isRequired Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor); if (matchingBeans.isEmpty()) { if (isRequired(descriptor)) { raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } return null; } 如果找到判断是否超过一个,如果只有一个则则直接返回该bean,如果是Class对象,则调用getBean生成该bean对象超过一个则调用determineAutowireCandidate(matchingBeans, descriptor) // 根据type找到了多个 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(); }在找到多个的情况下调用determineAutowireCandidate(matchingBeans, descriptor)
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 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; } 从多个Bean中选择被@Primary标注了的Bean,如果有多个@Primary会报错 String primaryCandidate = determinePrimaryCandidate(candidates, requiredType); if (primaryCandidate != null) { return primaryCandidate; } //--------------------------------------------------------------------- protected String determinePrimaryCandidate(Map<String, Object> candidates, Class<?> requiredType) { String primaryBeanName = null; for (Map.Entry<String, Object> entry : candidates.entrySet()) { String candidateBeanName = entry.getKey(); Object beanInstance = entry.getValue(); // 当前candidateBean是否@Primary if (isPrimary(candidateBeanName, beanInstance)) { if (primaryBeanName != null) { boolean candidateLocal = containsBeanDefinition(candidateBeanName); boolean primaryLocal = containsBeanDefinition(primaryBeanName); if (candidateLocal && primaryLocal) { throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(), "more than one 'primary' bean found among candidates: " + candidates.keySet()); } else if (candidateLocal) { primaryBeanName = candidateBeanName; } } else { primaryBeanName = candidateBeanName; } } } return primaryBeanName; } 如果没有@Primary,那么则看Bean上是否通过@Priority定义了优先级,如果定义了则获取优先级最高的Bean // 取优先级最高的bean String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType); if (priorityCandidate != null) { return priorityCandidate; } 如果没有优先级,那么使用descriptor.getDependencyName()来确定一个唯一的Bean判断是否找到唯一的Bean找到后如果不是Class对象直接返回,如果是就通过getBean获取如果没有找到,判断是否isRequired,如果是报错,不是就返回null 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; } } 整体流程