AutowiredAnnotationBeanPostProcessor是Spring的后置处理器,专门处理@Autowired和@Value注解。
postProcessMergedBeanDefinition
方法。 populateBean
进行属性注入的时候,即调用 postProcessPropertyValues
方法。 public AutowiredAnnotationBeanPostProcessor() { //后置处理器将处理@Autowire注解 this.autowiredAnnotationTypes.add(Autowired.class); //后置处理器将处理@Value注解 this.autowiredAnnotationTypes.add(Value.class); try { //后置处理器将处理javax.inject.Inject JSR-330注解 this.autowiredAnnotationTypes.add((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader())); logger.info("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring"); } catch (ClassNotFoundException ex) { // JSR-330 API not available - simply skip. } } 复制代码
//处理类中的属性,属性注入 @Override public PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException { //获取指定类中autowire相关注解的元信息 <1> InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs); try { //对Bean的属性进行自动注入 metadata.inject(bean, beanName, pvs); } catch (BeanCreationException ex) { throw ex; } catch (Throwable ex) { throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex); } return pvs; } 复制代码
该方法就是在属性注入populateBean中调用的 pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
的具体实现之一。
<1> 处的代码是从该bean中获取对应的注解信息,在 AutowiredAnnotationBeanPostProcessor
这里就是寻找有加@Value、@Autowired注解的字段,然后把相关信息封装在 InjectionMetadata
。这里的逻辑还是有些多的,之后会专门介绍,这里就不多说了。
直接看具体的注入逻辑:
//InjectionMetadata.java public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { Collection<InjectedElement> checkedElements = this.checkedElements; //要注入的字段集合 Collection<InjectedElement> elementsToIterate = (checkedElements != null ? checkedElements : this.injectedElements); if (!elementsToIterate.isEmpty()) { boolean debug = logger.isDebugEnabled(); //遍历每个字段 注入 for (InjectedElement element : elementsToIterate) { if (debug) { logger.debug("Processing injected element of bean '" + beanName + "': " + element); } element.inject(target, beanName, pvs); } } } 复制代码
这里还不是真正注入的方法,我们继续追踪 element.inject(target, beanName, pvs);
//InjectionMetadata.java protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs) throws Throwable { if (this.isField) { Field field = (Field) this.member; ReflectionUtils.makeAccessible(field); field.set(target, getResourceToInject(target, requestingBeanName)); } else { if (checkPropertySkipping(pvs)) { return; } try { Method method = (Method) this.member; ReflectionUtils.makeAccessible(method); method.invoke(target, getResourceToInject(target, requestingBeanName)); } catch (InvocationTargetException ex) { throw ex.getTargetException(); } } } 复制代码
这是 element.inject()
的原始方法,它还有两个子类自己实现的方法,如图:
AutowiredAnnotationBeanPostProcessor
具体的实现。
我们先来看下对字段的注入:
//AutowiredAnnotationBeanPostProcessor.java @Override protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { //获取要注入的字段 Field field = (Field) this.member; Object value; //如果字段的值有缓存 if (this.cached) { //从缓存中获取字段值value value = resolvedCachedArgument(beanName, this.cachedFieldValue); } //没有缓存 else { //创建一个字段依赖描述符 DependencyDescriptor desc = new DependencyDescriptor(field, this.required); desc.setContainingClass(bean.getClass()); Set<String> autowiredBeanNames = new LinkedHashSet<>(1); Assert.state(beanFactory != null, "No BeanFactory available"); //获取容器中的类型转换器 TypeConverter typeConverter = beanFactory.getTypeConverter(); try { //核心!获取注入的值 value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter); } catch (BeansException ex) { throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex); } //线程同步,确保容器中数据一致性 synchronized (this) { //如果字段的值没有缓存 if (!this.cached) { //字段值不为null,并且required属性为true if (value != null || this.required) { this.cachedFieldValue = desc; //为指定Bean注册依赖Bean registerDependentBeans(beanName, autowiredBeanNames); if (autowiredBeanNames.size() == 1) { String autowiredBeanName = autowiredBeanNames.iterator().next(); //如果容器中有指定名称的Bean对象 if (beanFactory.containsBean(autowiredBeanName)) { //依赖对象类型和字段类型匹配,默认按类型注入 if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) { //创建一个依赖对象的引用,同时缓存 this.cachedFieldValue = new ShortcutDependencyDescriptor( desc, autowiredBeanName, field.getType()); } } } } //如果获取的依赖关系为null,且获取required属性为false else { //将字段值的缓存设置为null this.cachedFieldValue = null; } //容器已经对当前字段的值缓存 this.cached = true; } } } //如果字段值不为null if (value != null) { //显式使用JDK的反射机制,设置自动的访问控制权限为允许访问 ReflectionUtils.makeAccessible(field); //为字段赋值 field.set(bean, value); } } 复制代码
这段代码很好理解,从注解@Value/@Autowired中获取要注入的值,之后利用反射set到字段中。
重点就是怎么从注解中获取要注入的值,我们来看核心代码 value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
//DefaultListableBeanFactory.java 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()) { 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 Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName); } else { Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary( descriptor, requestingBeanName); if (result == null) { //真正获取值的代码 result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); } return result; } } 复制代码
进行跟踪:
//DefaultListableBeanFactory.java public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor); try { 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()); return (descriptor.getField() != null ? converter.convertIfNecessary(value, type, descriptor.getField()) : converter.convertIfNecessary(value, type, descriptor.getMethodParameter())); } //如果标识@Autowired注解的属性是集合类型,Array,Collection,Map, // 从这个方法获取@Autowired里的值 <1> Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter); if (multipleBeans != null) { return multipleBeans; } //如果标识@Autowired注解的属性是非集合类型, // 从这个方法获取@Autowired里的值 <2> Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor); //如果没有符合该类型的Bean if (matchingBeans.isEmpty()) { //是否是必须的 if (isRequired(descriptor)) { //抛出异常 raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } return null; } String autowiredBeanName; Object instanceCandidate; //如果符合该类型的Bean有多个 if (matchingBeans.size() > 1) { //挑选出最优解 <3> autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor); if (autowiredBeanName == null) { if (isRequired(descriptor) || !indicatesMultipleBeans(type)) { //抛出异常 return descriptor.resolveNotUnique(type, 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; } finally { ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint); } } 复制代码
这段代码看着很长,但其实很容易理解。大致流程就是:
根据字段类型从IOC容器中获取符合的Bean,如果有多个,则挑选出最优的那一个。
下面来看下具体逻辑。
先来看下@Autowired注入集合数组的逻辑:
//DefaultListableBeanFactory.java private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) { Class<?> type = descriptor.getDependencyType(); //如果@Autowired标识的是数组类型的属性 if (type.isArray()) { //获取数组的内容类型 Class<?> componentType = type.getComponentType(); ResolvableType resolvableType = descriptor.getResolvableType(); Class<?> resolvedArrayType = resolvableType.resolve(); if (resolvedArrayType != null && resolvedArrayType != type) { type = resolvedArrayType; componentType = resolvableType.getComponentType().resolve(); } if (componentType == null) { return null; } //通过类型去IOC容器内择取符合的Bean都是使用这个方法 Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType, new MultiElementDescriptor(descriptor)); if (matchingBeans.isEmpty()) { return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); //将得到的Bean的候选者们转换为属性类型,如从set转换为Array,List等 Object result = converter.convertIfNecessary(matchingBeans.values(), type); if (getDependencyComparator() != null && result instanceof Object[]) { Arrays.sort((Object[]) result, adaptDependencyComparator(matchingBeans)); } return result; } else if (Collection.class.isAssignableFrom(type) && type.isInterface()) { //获取Collection的泛型 Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric(); if (elementType == null) { return null; } Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType, new MultiElementDescriptor(descriptor)); if (matchingBeans.isEmpty()) { return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); Object result = converter.convertIfNecessary(matchingBeans.values(), type); if (getDependencyComparator() != null && result instanceof List) { Collections.sort((List<?>) result, adaptDependencyComparator(matchingBeans)); } return result; } else if (Map.class == type) { ResolvableType mapType = descriptor.getResolvableType().asMap(); Class<?> keyType = mapType.resolveGeneric(0); if (String.class != keyType) { return null; } Class<?> valueType = mapType.resolveGeneric(1); if (valueType == null) { return null; } Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType, new MultiElementDescriptor(descriptor)); if (matchingBeans.isEmpty()) { return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } return matchingBeans; } else { return null; } } 复制代码
//DefaultListableBeanFactory.java protected Map<String, Object> findAutowireCandidates( @Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) { //从IOC容器中获取所有的符合类型的BeanName,存入候选数组 String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this, requiredType, true, descriptor.isEager()); Map<String, Object> result = new LinkedHashMap<>(candidateNames.length); //首先从容器自身注册的依赖解析来匹配,Spring容器自身注册了很多Bean的依赖, //当使用者想要注入指定类型的Bean时,会优先从已注册的依赖内寻找匹配 for (Class<?> autowiringType : this.resolvableDependencies.keySet()) { if (autowiringType.isAssignableFrom(requiredType)) { Object autowiringValue = this.resolvableDependencies.get(autowiringType); autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType); //如果注册的依赖Bean类型是指定类型的实例或是其父类,接口,则将其作为候选者,注册依赖的类型不会重复 if (requiredType.isInstance(autowiringValue)) { result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue); break; } } } //遍历候选数组 for (String candidate : candidateNames) { //候选Bean不是自引用(即要注入的类不能是类本身,会触发无限递归注入) if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) { addCandidateEntry(result, candidate, descriptor, requiredType); } } if (result.isEmpty() && !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)) { addCandidateEntry(result, candidate, descriptor, requiredType); } } if (result.isEmpty()) { // 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; } 复制代码
这段代码注释已经写的很清楚了,我们来继续看下 addCandidateEntry
方法,该方法是把Bean实例放入到候选者集合中
//DefaultListableBeanFactory.java private void addCandidateEntry(Map<String, Object> candidates, String candidateName, DependencyDescriptor descriptor, Class<?> requiredType) { //当@Autowired标识的是容器类型的属性,生成的依赖描述类型是MultiElementDescriptor , //因此所有的候选者均是合格的,所以会当场实例化他们。而如果属性的类型非容器,那么可能是多个候选者中挑一个, //此时实例化他们所有就不合适了,最终会把合格的那个实例化,如果没有合格的则不实例化, //提前实例化对Bean的很多方面有影响,比如AOP,EarlyReference等 */ if (descriptor instanceof MultiElementDescriptor || containsSingleton(candidateName)) { Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this); candidates.put(candidateName, (beanInstance instanceof NullBean ? null : beanInstance)); } else { candidates.put(candidateName, getType(candidateName)); } } 复制代码
这里会调用doGetBean()方法进行实例化Bean
如果根据类型从IOC容器中获得的Bean有多个,那么就需要调用 determineAutowireCandidate(matchingBeans, descriptor)
方法,去挑选出最优解。
代码:
//DefaultListableBeanFactory.java protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) { Class<?> requiredType = descriptor.getDependencyType(); //根据@Primary注解来择取最优解 String primaryCandidate = determinePrimaryCandidate(candidates, requiredType); if (primaryCandidate != null) { return primaryCandidate; } //根据@Order,@PriorityOrder,及实现Order接口的序号来择取最优解 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(); //如果通过以上两步都不能选择出最优解,则使用最基本的策略 //首先如果这个类型已经由Spring注册过依赖关系对,则直接使用注册的对象, //候选者集合是LinkedHashMap,有序Map集合,容器注册的依赖对象位于LinkedHashMap的起始位置 //如果没有注册过此类型的依赖关系,则根据属性的名称来匹配,、 //如果属性名称和某个候选者的Bean名称或别名一致,那么直接将此Bean作为最优解 if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) || matchesBeanName(candidateName, descriptor.getDependencyName())) { return candidateName; } } return null; } 复制代码
这部分逻辑比较简单,总结就是3个步骤:
我们逐一分析这几个步骤,先看第一个:
根据@Primary注解来择取最优解
//DefaultListableBeanFactory.java 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(); //候选者可以是父容器内的标识了@Primary的Bean,也可以是当前容器的。SpringMVC容器将Spring容器作为父容器 if (isPrimary(candidateBeanName, beanInstance)) { if (primaryBeanName != null) { boolean candidateLocal = containsBeanDefinition(candidateBeanName); boolean primaryLocal = containsBeanDefinition(primaryBeanName); //此处确保同一个容器中同一个类型的多个Bean最多只有一个Bean标识了@Primary if (candidateLocal && primaryLocal) { throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(), "more than one 'primary' bean found among candidates: " + candidates.keySet()); } //如果上一个@Primary的Bean是父容器的,则用当前容器的候选者覆盖之前的@Primary的Bean else if (candidateLocal) { primaryBeanName = candidateBeanName; } } else { primaryBeanName = candidateBeanName; } } } return primaryBeanName; } 复制代码
接着看第二个:
根据@Order,@PriorityOrder
//DefaultListableBeanFactory.java protected String determineHighestPriorityCandidate(Map<String, Object> candidates, Class<?> requiredType) { String highestPriorityBeanName = null; Integer highestPriority = null; for (Map.Entry<String, Object> entry : candidates.entrySet()) { String candidateBeanName = entry.getKey(); Object beanInstance = entry.getValue(); Integer candidatePriority = getPriority(beanInstance); if (candidatePriority != null) { //不能同时存在两个最高优先级的序号 if (highestPriorityBeanName != null) { if (candidatePriority.equals(highestPriority)) { throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(), "Multiple beans found with the same priority ('" + highestPriority + "') among candidates: " + candidates.keySet()); } //使用优先级序号最小的Bean作为最优解 else if (candidatePriority < highestPriority) { highestPriorityBeanName = candidateBeanName; highestPriority = candidatePriority; } } else { highestPriorityBeanName = candidateBeanName; highestPriority = candidatePriority; } } } return highestPriorityBeanName; } 复制代码
小结:
到这里,@Autowired字段注入的源码就分析完毕了。
接下来我们看下方法注入:
//DefaultListableBeanFactory.java protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { //如果属性被显式设置为skip,则不进行注入 if (checkPropertySkipping(pvs)) { return; } //获取注入元素对象 Method method = (Method) this.member; Object[] arguments; //如果容器对当前方法缓存 if (this.cached) { // Shortcut for avoiding synchronization... //获取缓存中指定Bean名称的方法参数 arguments = resolveCachedArguments(beanName); } //如果没有缓存 else { //获取方法的参数列表 Class<?>[] paramTypes = method.getParameterTypes(); //创建一个存放方法参数的数组 arguments = new Object[paramTypes.length]; DependencyDescriptor[] descriptors = new DependencyDescriptor[paramTypes.length]; Set<String> autowiredBeans = new LinkedHashSet<>(paramTypes.length); Assert.state(beanFactory != null, "No BeanFactory available"); //获取容器的类型转换器 TypeConverter typeConverter = beanFactory.getTypeConverter(); for (int i = 0; i < arguments.length; i++) { //创建方法参数对象 MethodParameter methodParam = new MethodParameter(method, i); DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required); currDesc.setContainingClass(bean.getClass()); //解析方法的输入参数,为方法参数创建依赖描述符 descriptors[i] = currDesc; try { Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter); if (arg == null && !this.required) { arguments = null; break; } //根据容器中Bean定义解析依赖关系,获取方法参数依赖对象 arguments[i] = arg; } catch (BeansException ex) { throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex); } } //线程同步,以确保容器中数据一致性 synchronized (this) { //如果当前方法没有被容器缓存 if (!this.cached) { //如果方法的参数列表不为空 if (arguments != null) { //为容器中缓存方法参数的对象赋值 Object[] cachedMethodArguments = new Object[paramTypes.length]; for (int i = 0; i < arguments.length; i++) { cachedMethodArguments[i] = descriptors[i]; } //为指定Bean注册依赖Bean registerDependentBeans(beanName, autowiredBeans); //如果依赖对象集合大小等于方法参数个数 if (autowiredBeans.size() == paramTypes.length) { Iterator<String> it = autowiredBeans.iterator(); //为方法参数设置依赖对象 for (int i = 0; i < paramTypes.length; i++) { String autowiredBeanName = it.next(); //如果容器中存在指定名称的Bean对象 if (beanFactory.containsBean(autowiredBeanName)) { //如果参数类型和依赖对象类型匹配 if (beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) { //创建一个依赖对象的引用,复制给方法相应的参 cachedMethodArguments[i] = new ShortcutDependencyDescriptor( descriptors[i], autowiredBeanName, paramTypes[i]); } } } } this.cachedMethodArguments = cachedMethodArguments; } //如果方法参数列表为null,则设置容器对该方法参数的缓存为null else { this.cachedMethodArguments = null; } //设置容器已经对该方法缓存 this.cached = true; } } } //如果方法参数依赖对象不为null if (arguments != null) { try { //使用JDK的反射机制,显式设置方法的访问控制权限为允许访问 ReflectionUtils.makeAccessible(method); //调用Bean的指定方法 method.invoke(bean, arguments); } catch (InvocationTargetException ex){ throw ex.getTargetException(); } } } 复制代码
@Autowired注解的原理用一句话讲明:
就是先从IOC容器中根据类型找到所有符合的Bean,然后再根据@Primary、@Order、@PriorityOrder或Spring默认规则挑选出最符合的Bean,利用反射注入到字段中。