Spring對BeanFactory底層的最終實現是DefaultListableBeanFactory,DefaultListableBeanFactory對resolveDependency方法實現的源碼以下。java
/** * @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爲例源碼以下ide
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方法ui
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方法this
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方法lua
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。code