AutowiredAnnotationBeanPostProcessor是Spring的後置處理器,專門處理@Autowired和@Value註解。java
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
。這裏的邏輯仍是有些多的,以後會專門介紹,這裏就很少說了。緩存
直接看具體的注入邏輯:app
//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);
ide
//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
具體的實現。post
咱們先來看下對字段的注入:ui
//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);
this
//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; } }
進行跟蹤:lua
//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,利用反射注入到字段中。