Spring IOC容器 源碼解析系列,建議你們按順序閱讀,歡迎討論spring
(spring源碼均爲4.1.6.RELEASE版本)緩存
部門有實習生來的時候,都會先了解系統的基本架構,再寫一個基本的demo。一般強調的就是新建的類上要加@Controller或@Service,而類中的引用的其餘對象的屬性上加上@Autowired,而後寫點增刪改查就ok了。通常初學一個框架時只需知道如何使用,但想要用的好,就必需要深刻了解其原理。所謂知其然,也要知其因此然。在Spring使用註解後,由於其自己就是非侵入式的設計,致使使用的人能感知到的就是幾個註解。這樣的框架的設計天然是極好的,對於使用的人來講,更是值得學習。數據結構
@Controller和@Service都是繼承自@Component,只是分別標識Controller層和Service層,用於對類進行分類。@Component做爲Spring的類掃描的默認註解,在Spring源碼-IOC容器(九)-Component-Scan源碼解析中已介紹過。而@Autowired能夠說是Spring依賴注入的最重要的註解,本章就來詳細解析它的使用原理。架構
@Autowired最經常使用的方式就是放在屬性或setter方法上,而其還能放在構造函數以及非setter方法的任意方法上。app
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Autowired { /** * Declares whether the annotated dependency is required. * <p>Defaults to {@code true}. */ boolean required() default true; }
能夠看到支持的目標包括構造函數,屬性,方法,也能夠被做爲元註解。這裏須要強調的有兩個:框架
@Autowired是根據對象類型來進行匹配的,若是想經過指定具體的bean的名稱,可使用@Qualifier。@Autowired只有required屬性能夠設置,默認爲true,即默認必須能匹配到相應的bean,不然就會報出NoSuchBeanDefinitionException異常。若是容許依賴注入失敗,則能夠設置required=false。ide
@Autowired的解析器是AutowiredAnnotationBeanPostProcessor,它是BeanPostProcessor後置處理器的子類。若是經過BeanFactory的啓動方式,須要手動注入。函數
xml文件post
<bean id="autowiredAnnotationBeanPostProcessor" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
而且經過學習
beanFactory.addBeanPostProcessor((BeanPostProcessor) beanFactory. getBean("autowiredAnnotationBeanPostProcessor"));
添加到beanPostProcessor集合中。
但一般狀況下component-scan掃描的配置處理中默認就加載了AutowiredAnnotationBeanPostProcessor。
<context:component-scan base-package=".."/>
若是不使用component-scan的掃描配置,能夠經過
<context:annotation-config/>
來默認配置。
在Spring的bean實例化過程當中有許多BeanPostProcessor擴展點,支持內置的以及用戶自定義的BeanPostProcessor對bean的實例化進行干預和操做。BeanPostProcessor接口自己只支持bean的初始化先後的擴展,但它的子接口則增長了更多擴展點。
對於AutowiredAnnotationBeanPostProcessor,先來看它的實現
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware
它實現了MergedBeanDefinitionPostProcessor接口,而繼承的InstantiationAwareBeanPostProcessorAdapter實際上是SmartInstantiationAwareBeanPostProcessor接口的默認實現類。因此基本支持了全部的擴展點,但不少都是繼承的默認方法,主要實現的有三個方法:
第一個方法支撐了@Autowired做用於構造函數,第二和三方法支撐了@Autowired做用於屬性和方法。
在AbstractAutowireCapableBeanFactory中的createBeanInstance方法中,對bean進行實例化操做。若是沒有經過xml指定構造函數或工廠方法,則會判斷是否有InstantiationAwareBeanPostProcessor註冊到容器中,並判斷是否爲其子接口SmartInstantiationAwareBeanPostProcessor的實現類,而後調用determineCandidateConstructors方法返回構造函數候選者集合。
AbstractAutowireCapableBeanFactory.createBeanInstance() // Need to determine the constructor... Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(Class<?> beanClass, String beanName) throws BeansException { if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName); if (ctors != null) { return ctors; } } } } return null; }
此時就進入AutowiredAnnotationBeanPostProcessor的determineCandidateConstructors方法中
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName) throws BeansException { // 解析Lookup註解,並設置到BeanDefinition中 if (!this.lookupMethodsChecked.contains(beanName)) { ReflectionUtils.doWithMethods(beanClass, new ReflectionUtils.MethodCallback() { @Override public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { Lookup lookup = method.getAnnotation(Lookup.class); if (lookup != null) { LookupOverride override = new LookupOverride(method, lookup.value()); try { RootBeanDefinition mbd = (RootBeanDefinition) beanFactory.getMergedBeanDefinition(beanName); mbd.getMethodOverrides().addOverride(override); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(beanName, "Cannot apply @Lookup to beans without corresponding bean definition"); } } } }); this.lookupMethodsChecked.add(beanName); } // Quick check on the concurrent map first, with minimal locking. Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass); if (candidateConstructors == null) { synchronized (this.candidateConstructorsCache) { candidateConstructors = this.candidateConstructorsCache.get(beanClass); if (candidateConstructors == null) { // 拿到全部public的構造函數 Constructor<?>[] rawCandidates = beanClass.getDeclaredConstructors(); List<Constructor<?>> candidates = new ArrayList<Constructor<?>>(rawCandidates.length); Constructor<?> requiredConstructor = null; Constructor<?> defaultConstructor = null; for (Constructor<?> candidate : rawCandidates) { // 尋找構造函數上的@Autowired註解 AnnotationAttributes ann = findAutowiredAnnotation(candidate); if (ann != null) { // 只容許有一個required=true的@Autowired if (requiredConstructor != null) { throw new BeanCreationException(beanName, "Invalid autowire-marked constructor: " + candidate + ". Found constructor with 'required' Autowired annotation already: " + requiredConstructor); } // 無參構造函數上設置@Autowired拋出異常 if (candidate.getParameterTypes().length == 0) { throw new IllegalStateException( "Autowired annotation requires at least one argument: " + candidate); } boolean required = determineRequiredStatus(ann); if (required) { if (!candidates.isEmpty()) { throw new BeanCreationException(beanName, "Invalid autowire-marked constructors: " + candidates + ". Found constructor with 'required' Autowired annotation: " + candidate); } requiredConstructor = candidate; } candidates.add(candidate); } else if (candidate.getParameterTypes().length == 0) { defaultConstructor = candidate; } } if (!candidates.isEmpty()) { // Add default constructor to list of optional constructors, as fallback. if (requiredConstructor == null) { if (defaultConstructor != null) { candidates.add(defaultConstructor); } else if (candidates.size() == 1 && logger.isWarnEnabled()) { logger.warn("Inconsistent constructor declaration on bean with name '" + beanName + "': single autowire-marked constructor flagged as optional - this constructor " + "is effectively required since there is no default constructor to fall back to: " + candidates.get(0)); } } candidateConstructors = candidates.toArray(new Constructor<?>[candidates.size()]); } else { candidateConstructors = new Constructor<?>[0]; } this.candidateConstructorsCache.put(beanClass, candidateConstructors); } } } return (candidateConstructors.length > 0 ? candidateConstructors : null); }
基本步驟爲:
返回的構造函數集合根據必定的策略找到最佳的一個,而後經過newInstance方法實例化bean對象。
在bean實例化完成後,MergedBeanDefinitionPostProcessor的擴展點支持對BeanDefinition進行處理。
AbstractAutowireCapableBeanFactory.doCreateBean() // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); mbd.postProcessed = true; } }
而在AutowiredAnnotationBeanPostProcessor的實現中,經過查找並組裝全部有@Autowired的屬性及方法。
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) { if (beanType != null) { // 查找全部@Autowired的屬性和方法,組裝成InjectionMetadata,存放到Map中 InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null); metadata.checkConfigMembers(beanDefinition); } }
在findAutowiringMetadata方法中,對屬性和方法分開解析並組裝不一樣的數據結構中,AutowiredFieldElement和AutowiredMethodElement。
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, PropertyValues pvs) { // Fall back to class name as cache key, for backwards compatibility with custom callers. // 緩存key爲bean名稱 String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName()); // Quick check on the concurrent map first, with minimal locking. // 先從Map中查詢是否存在 InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey); if (InjectionMetadata.needsRefresh(metadata, clazz)) { synchronized (this.injectionMetadataCache) { metadata = this.injectionMetadataCache.get(cacheKey); if (InjectionMetadata.needsRefresh(metadata, clazz)) { if (metadata != null) { metadata.clear(pvs); } try { // 構建元數據數據結構 metadata = buildAutowiringMetadata(clazz); this.injectionMetadataCache.put(cacheKey, metadata); } catch (NoClassDefFoundError err) { throw new IllegalStateException("Failed to introspect bean class [" + clazz.getName() + "] for autowiring metadata: could not find class that it depends on", err); } } } } return metadata; } // 根據Class對象,對屬性和方法分別進行組裝 private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) { LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>(); Class<?> targetClass = clazz; do { LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<InjectionMetadata.InjectedElement>(); // 屬性 for (Field field : targetClass.getDeclaredFields()) { AnnotationAttributes ann = findAutowiredAnnotation(field); if (ann != null) { if (Modifier.isStatic(field.getModifiers())) { if (logger.isWarnEnabled()) { logger.warn("Autowired annotation is not supported on static fields: " + field); } continue; } boolean required = determineRequiredStatus(ann); currElements.add(new AutowiredFieldElement(field, required)); } } // 方法 for (Method method : targetClass.getDeclaredMethods()) { Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) { continue; } AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod); if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) { if (Modifier.isStatic(method.getModifiers())) { if (logger.isWarnEnabled()) { logger.warn("Autowired annotation is not supported on static methods: " + method); } continue; } if (method.getParameterTypes().length == 0) { if (logger.isWarnEnabled()) { logger.warn("Autowired annotation should be used on methods with actual parameters: " + method); } } boolean required = determineRequiredStatus(ann); PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz); currElements.add(new AutowiredMethodElement(method, required, pd)); } } elements.addAll(0, currElements); targetClass = targetClass.getSuperclass(); } while (targetClass != null && targetClass != Object.class); return new InjectionMetadata(clazz, elements); }
這樣在實例化後,bean中全部@Autowired的屬性和方法都被組裝成InjectionMetadata存儲到以bean名稱爲key的Map中。
AbstractAutowireCapableBeanFactory的populateBean方法用來對bean進行依賴注入,而在真正的依賴注入前,一樣檢查是否有InstantiationAwareBeanPostProcessor,並調用postProcessPropertyValues方法對bean的依賴進行外部擴展處理。
AutowiredAnnotationBeanPostProcessor的postProcessPropertyValues也很是清晰。
public PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { // 再次查找全部@Autowired的屬性和方法,若是有緩存,直接從緩存中獲取 InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs); try { // 執行屬性的依賴注入和方法的執行 metadata.inject(bean, beanName, pvs); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex); } return pvs; }
findAutowiringMetadata在上面已經介紹過了,此時直接從Map的緩存中獲取便可。主要來看InjectionMetadata的inject方法。
public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable { Collection<InjectedElement> elementsToIterate = (this.checkedElements != null ? this.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); } } }
遍歷取出全部的InjectedElement,包括屬性和方法,分別執行inject方法。
1.AutowiredFieldElement
主要的操做是
經過beanFactory的resolveDependency方法從beanFactory中匹配相同類型的BeanDefition,並經過getBean方法實例化對象,若是有多個匹配項,默認返回第一個。
向容器註冊依賴關係,並緩存RuntimeBeanReference類型的FieldValue
經過反射注入屬性值
protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable { Field field = (Field) this.member; try { Object value; if (this.cached) { value = resolvedCachedArgument(beanName, this.cachedFieldValue); } else { DependencyDescriptor desc = new DependencyDescriptor(field, this.required); desc.setContainingClass(bean.getClass()); Set<String> autowiredBeanNames = new LinkedHashSet<String>(1); TypeConverter typeConverter = beanFactory.getTypeConverter(); // 從beanFactory匹配類型相同的bean對象 value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter); synchronized (this) { if (!this.cached) { if (value != null || this.required) { this.cachedFieldValue = desc; // 註冊對象依賴關係 registerDependentBeans(beanName, autowiredBeanNames); if (autowiredBeanNames.size() == 1) { String autowiredBeanName = autowiredBeanNames.iterator().next(); if (beanFactory.containsBean(autowiredBeanName)) { if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) { this.cachedFieldValue = new RuntimeBeanReference(autowiredBeanName); } } } } else { this.cachedFieldValue = null; } this.cached = true; } } } if (value != null) { // 反射注入屬性值 ReflectionUtils.makeAccessible(field); field.set(bean, value); } } catch (Throwable ex) { throw new BeanCreationException("Could not autowire field: " + field, ex); } }
}
2.AutowiredMethodElement
方法的操做同屬性相近,只是根據方法中的每一個參數的類型去beanFactory中去匹配bean對象。
遍歷方法中的全部參數,按照類型從beanFactory中匹配相應的BeanDefition並實例化,過程同AutowiredFieldElement中一致
註冊對象依賴關係,方法中全部的參數都是bean的依賴方,而後每一個參數分別緩存爲RuntimeBeanReference類型的結構。
調用反射方法執行方法
protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable { if (checkPropertySkipping(pvs)) { return; } Method method = (Method) this.member; try { Object[] arguments; if (this.cached) { // Shortcut for avoiding synchronization... arguments = resolveCachedArguments(beanName); } else { Class<?>[] paramTypes = method.getParameterTypes(); arguments = new Object[paramTypes.length]; DependencyDescriptor[] descriptors = new DependencyDescriptor[paramTypes.length]; Set<String> autowiredBeanNames = new LinkedHashSet<String>(paramTypes.length); TypeConverter typeConverter = beanFactory.getTypeConverter(); // 遍歷方法中的參數,查找對應的bean實例 for (int i = 0; i < arguments.length; i++) { MethodParameter methodParam = new MethodParameter(method, i); DependencyDescriptor desc = new DependencyDescriptor(methodParam, this.required); desc.setContainingClass(bean.getClass()); descriptors[i] = desc; Object arg = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter); if (arg == null && !this.required) { arguments = null; break; } arguments[i] = arg; } synchronized (this) { if (!this.cached) { if (arguments != null) { this.cachedMethodArguments = new Object[arguments.length]; for (int i = 0; i < arguments.length; i++) { this.cachedMethodArguments[i] = descriptors[i]; } // 註冊全部的參數爲bean的依賴方 registerDependentBeans(beanName, autowiredBeanNames); if (autowiredBeanNames.size() == paramTypes.length) { Iterator<String> it = autowiredBeanNames.iterator(); for (int i = 0; i < paramTypes.length; i++) { String autowiredBeanName = it.next(); if (beanFactory.containsBean(autowiredBeanName)) { if (beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) { this.cachedMethodArguments[i] = new RuntimeBeanReference(autowiredBeanName); } } } } } else { this.cachedMethodArguments = null; } this.cached = true; } } } if (arguments != null) { // 反射執行方法 ReflectionUtils.makeAccessible(method); method.invoke(bean, arguments); } } catch (InvocationTargetException ex) { throw ex.getTargetException(); } catch (Throwable ex) { throw new BeanCreationException("Could not autowire method: " + method, ex); } }
這樣全部的@Autowired設置都執行完成,註解方式的依賴注入就經過BeanPostProcessor這種擴展點的方式完成。