@Autowired註解源碼解析

咱們先來寫一個簡單的demo方便debug調試。緩存

public class QualifierDemo {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext();
        applicationContext.register(QualifierDemo.class);
        applicationContext.refresh();

        applicationContext.close();
    }

    @Autowired
    private User user;


    @Bean
    public User user(){
        return createUser("user1");
    }

    private static User createUser(String name){
        User user=new User();
        user.setName(name);
        return user;
    }
}

首先咱們來關注這個方法AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition,這個類實現了BeanPostProcessor的子接口,因此bean在實例化的時候會執行到這個方法。app

@Override
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
	    //獲取加了@Autowired的元信息數據
		InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
		//將beanDefinition裏Autowired相關信息添加到checkedElements裏面,後面會用到。
		metadata.checkConfigMembers(beanDefinition);
	}

咱們能夠看到上面這個方法到入參裏有個beanDefinition,這個beanDefinition正是QualifierDemo的實例,而後經過findAutowiringMetadata方法會去找關於Autowired的元信息。
這個方法執行完後,會執行AutowiredAnnotationBeanPostProcessor#postProcessProperties方法。ide

@Override
	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
	    //獲取一些元信息
		InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
		try {
		    //關鍵的方法
			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;
	}

這裏面關鍵的方法就是inject方法,他的代碼以下:post

public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
        //取以前存入的checkedElements
		Collection<InjectedElement> checkedElements = this.checkedElements;
		//沒有的話就取injectedElements,也是以前存入的
		Collection<InjectedElement> elementsToIterate =
				(checkedElements != null ? checkedElements : this.injectedElements);
		if (!elementsToIterate.isEmpty()) {
		    //遍歷@Autowired註解標記了的元信息數據集合,咱們的示例中只有一個@Autowired  User
			for (InjectedElement element : elementsToIterate) {
				if (logger.isTraceEnabled()) {
					logger.trace("Processing injected element of bean '" + beanName + "': " + element);
				}
				//element正是咱們示例代碼裏的User的一些描述
				element.inject(target, beanName, pvs);
			}
		}
	}

element的結構圖以下:

能夠看出,這個類型就是咱們的User。接着往下看element#inject方法。ui

@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 = 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 {
				    //根據元信息描述去進行bean查找
					value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
				}
				catch (BeansException ex) {
					throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
				}
				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) &&
										beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
									this.cachedFieldValue = new ShortcutDependencyDescriptor(
											desc, autowiredBeanName, field.getType());
								}
							}
						}
						else {
							this.cachedFieldValue = null;
						}
						this.cached = true;
					}
				}
			}
			//將查找到的bean經過反射set到對象中及示例中的 @Autowired private User user;
			if (value != null) {
			    //反射操做給private屬性須要的操做。
				ReflectionUtils.makeAccessible(field);
				field.set(bean, value);
			}
		}
	}

經過反射將查找到到bean注入到@Autowired註解到變量上。this

相關文章
相關標籤/搜索