@Autowired
註解的實現過程,其實就是Spring Bean的自動裝配過程。經過看@Autowired源碼註釋部分咱們能夠看到@Autowired
的實現是經過AutowiredAnnotationBeanPostProcessor
後置處理器中實現的。java
AutowiredAnnotationBeanPostProcessor
後置處理器的執行優先級AutowiredAnnotationBeanPostProcessor
能夠直接經過BeanFactory
獲取容器中的Bean在分析自動裝配前咱們先來介紹一下上面的這些後置處理器。spring
BeanPostProcessor有兩個方法,postProcessBeforeInitialization
和postProcessAfterInitialization
。它們分別在任何bean初始化回調以前或以後執行(例如InitializingBean的afterPropertiesSet方法或自定義init-method方法以前或者以後), 在這個時候該bean的屬性值已經填充完成了,而且咱們返回的bean實例可能已是原始實例的包裝類型了。例如返回一個FactoryBean
。緩存
InstantiationAwareBeanPostProcessor
繼承自BeanPostProcessor
接口。主要多提供瞭如下三個方法。app
該方法是在Bean實例化目標對象以前調用,返回的Bean對象能夠代理目標,從而有效的阻止了目標Bean的默認實例化。ide
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { // Make sure bean class is actually resolved at this point. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null) { bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { // 若是此方法返回一個非null對象,則Bean建立過程將被短路。 // 惟一應用的進一步處理是來自已配置BeanPostProcessors的postProcessAfterInitialization回調 bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null); } return bean; } protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // 執行Bean實例化目標對象以前的後置處理方法 Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } } return null; }
跟進源碼咱們能夠看出,若是此方法返回一個非null對象,則Bean建立過程將被短路。惟一應用的進一步處理是來自已配置BeanPostProcessors的postProcessAfterInitialization回調。函數
該方法執行在經過構造函數或工廠方法在實例化bean以後但在發生Spring屬性填充(經過顯式屬性或自動裝配)以前執行操做。這是在Spring的自動裝配開始以前對給定的bean實例執行自定義字段注入的理想回調。若是該方法返回false,那麼它會阻斷後續InstantiationAwareBeanPostProcessor
後置處理器的執行,而且會阻止後續屬性填充的執行邏輯。post
在工廠將給定屬性值應用於給定bean以前,對它們進行後處理。容許檢查是否知足全部依賴關係,例如基於bean屬性設置器上的「 Required」註解。還容許替換要應用的屬性值,一般是經過基於原始PropertyValues建立新的MutablePropertyValues實例,添加或刪除特定值來實現。ui
智能實例化Bean的後處理器,主要提供了三個方法。this
預測今後處理器的postProcessBeforeInstantiation回調最終返回的bean的類型。.net
肯定使用實例化Bean的構造函數。
獲取提前暴露的Bean的引用,提前暴露的Bean就是隻完成了實例化,還未完成屬性賦值和初始化的Bean。
合併Bean的定義信息的後處理方法,該方法是在Bean的實例化以後設置值以前調用。
AutowiredAnnotationBeanPostProcessor
後置處理器主要負責對添加了@Autowired和@Value註解的元素實現自動裝配。因此找到須要自動裝配的元素,其實就是對@Autowired和@Value註解的解析。
AutowiredAnnotationBeanPostProcessor
後置處理器,找出須要自動裝配的元素是在MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition
這個方法中實現的,調用鏈路以下:
doWith:445, AutowiredAnnotationBeanPostProcessor$2 (org.springframework.beans.factory.annotation) doWithLocalFields:657, ReflectionUtils (org.springframework.util) buildAutowiringMetadata:433, AutowiredAnnotationBeanPostProcessor (org.springframework.beans.factory.annotation) findAutowiringMetadata:412, AutowiredAnnotationBeanPostProcessor (org.springframework.beans.factory.annotation) postProcessMergedBeanDefinition:235, AutowiredAnnotationBeanPostProcessor (org.springframework.beans.factory.annotation) applyMergedBeanDefinitionPostProcessors:1000, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) doCreateBean:523, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) createBean:483, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) getObject:312, AbstractBeanFactory$1 (org.springframework.beans.factory.support) getSingleton:230, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support) doGetBean:308, AbstractBeanFactory (org.springframework.beans.factory.support) getBean:197, AbstractBeanFactory (org.springframework.beans.factory.support) preInstantiateSingletons:761, DefaultListableBeanFactory (org.springframework.beans.factory.support) finishBeanFactoryInitialization:867, AbstractApplicationContext (org.springframework.context.support) refresh:543, AbstractApplicationContext (org.springframework.context.support) <init>:84, AnnotationConfigApplicationContext (org.springframework.context.annotation)
從鏈路上咱們能夠看到,找到須要自動裝配的元素是在findAutowiringMetadata
方法中實現的,該方法會去調用buildAutowiringMetadata
方法構建元數據信息。若是註解被加載屬性上將會被封裝成AutowiredFieldElement
對象;若是註解加在方法上,那麼元素會被封裝成AutowiredMethodElement
對象。這裏兩個對象的inject
方法將最後完成屬性值的注入,主要區別就是使用反射注入值的方式不同。源碼以下:
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) { LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>(); Class<?> targetClass = clazz; do { // 存放咱們找到的元數據信息 final LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<InjectionMetadata.InjectedElement>(); // 經過反射找出對應Class對象的全部Field ReflectionUtils.doWithLocalFields(targetClass, new ReflectionUtils.FieldCallback() { @Override public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException { // 經過反射找到該字段上全部的註解信息,並判斷是否有@Autowired和@Value註解,若是有就將該字段封成AutowiredFieldElement對象 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); } return; } boolean required = determineRequiredStatus(ann);、 // 將該字段封成AutowiredFieldElement對象,並放到緩存中 currElements.add(new AutowiredFieldElement(field, required)); } } }); // 經過反射找出對應Class對象的全部Method ReflectionUtils.doWithLocalMethods(targetClass, new ReflectionUtils.MethodCallback() { @Override public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) { return; } // 經過反射找到該字段上全部的註解信息,並判斷是否有@Autowired和@Value註解,若是有就將該字段封成AutowiredMethodElement對象 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); } return; } if (method.getParameterTypes().length == 0) { if (logger.isWarnEnabled()) { logger.warn("Autowired annotation should only be used on methods with parameters: " + method); } } boolean required = determineRequiredStatus(ann); PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz); // 將該字段封成AutowiredMethodElement對象 currElements.add(new AutowiredMethodElement(method, required, pd)); } } }); elements.addAll(0, currElements); targetClass = targetClass.getSuperclass(); } // 循環處理父類須要自動裝配的元素 while (targetClass != null && targetClass != Object.class); // 將須要自動裝配的元素封裝成InjectionMetadata對象,最後合併到Bean定義中 return new InjectionMetadata(clazz, elements); }
尋找須要自動裝配過程:
Field
和```Method````對象Field
和Method
上的註解,並判斷是否有@Autowired和@Value註解Field
和Method
封裝成AutowiredFieldElement
和AutowiredMethodElement
對象,等待下一步的自動裝配。externallyManagedConfigMembers
屬性中AutowiredAnnotationBeanPostProcessor
後置處理器注入屬性值是在postProcessPropertyValues
方法中實現的。源碼以下:
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); } // 調用AutowiredFieldElement或AutowiredMethodElement對象的inject方法注入屬性值 element.inject(target, beanName, pvs); } } }
@Override protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable { Field field = (Field) this.member; 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(); try { // 在容器中獲取須要裝配的Bean value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter); } ... } if (value != null) { // 經過反射設置屬性值 ReflectionUtils.makeAccessible(field); field.set(bean, value); } }
@Override protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable { if (checkPropertySkipping(pvs)) { return; } Method method = (Method) this.member; 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> autowiredBeans = new LinkedHashSet<String>(paramTypes.length); 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 { // 在容器中獲取須要裝配的Bean Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter); if (arg == null && !this.required) { arguments = null; break; } arguments[i] = arg; } catch (BeansException ex) { throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex); } } ... } if (arguments != null) { try { // 經過反射調用方法設置元素值 ReflectionUtils.makeAccessible(method); method.invoke(bean, arguments); } ... } }
從這裏的源碼咱們能夠看出AutowiredFieldElement
和AutowiredMethodElement
完成自動裝配都是先去容器中找對應的Bean,而後經過反射將獲取到的Bean設置到目標對象中,來完成Bean的自動裝配。
咱們能夠看出Spring Bean的自動裝配過程就是:
Class
對象,經過反射獲取全部的Field
和Method
信息Field
和Method
的註解信息,並根據註解類型,判斷是否須要自動裝配AutowiredFieldElement
或AutowiredMethodElement
對象AutowiredFieldElement
或AutowiredMethodElement
的inject
方法,喚起後續步驟getBean()
方法找到須要注入的源數據Bean在自動裝配過程當中還涉及循環依賴的問題,有興趣的能夠看下這篇文章Spring 源碼(八)循環依賴
注意:註解注入將在XML注入以前執行;所以,對於經過這兩種方法注入的屬性,XML注入將覆蓋註解注入。