Spring @Autowired注解的实现原理

1、@Autowired注解是如何实现自动装配的?
2、当为类型为OrderService的Bean装配类型为UserService的属性时,如果此时Spring容器中存在多个类型为UserService的bean,此时Spring是如何处理的?
3、自动装配的模型是什么?有哪几种?和Autowired注解有什么关联?

@Autowired 自动装配是通过后置处理器来完成的。这个后置处理器就是 AutowiredAnnotationBeanPostProcessor

要解决上面说的问题,就要了解 Spring Bean生命周期 以及 @AutoWirte的原理,这块需要看对应的源码

@Autowirte如何实现自动装配

// TODO 流程图

@Autowirte自动装配源码详解

@Autowired 自动装配是通过AutowiredAnnotationBeanPostProcessor这个后置处理器来完成的。具体是怎么实现的呢?
1、在容器启动前会注册内置AutowiredAnnotationBeanPostProcessor后置处理器
2、在容器启动时refresh()时,调用 registerBeanPostProcessors(beanFactory) 方法获取并把AutowiredAnnotationBeanPostProcessor注册到beanFactory里
3、在创建bean执行到populateBean方法会调用AutowiredAnnotationBeanPostProcessorpostProcessProperties方法,在这个方法里会解析出带有@Autowired注解、@Inject和@Value的属性和方法,通过反射完成注入。

(2.1) 容器启动前注册内置BeanPostProcessor

当我们调用AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class)启动容器的时候,在构造方法中会调用到this()方法,
在this()方法中最终会调用 AnnotationConfigUtils 的 registerAnnotationConfigProcessors(BeanDefinitionRegistry) 方法,在该方法中,Spring会向容器注册7个Spring内置的Bean,其中就包括AutowiredAnnotationBeanPostProcessor。

/**
	* Register all relevant annotation post processors in the given registry.
	* @param registry the registry to operate on
	* @param source the configuration source element (already extracted)
	* that this registration was triggered from. May be {@code null}.
	* @return a Set of BeanDefinitionHolders, containing all bean definitions
	* that have actually been registered by this call
	*/
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
		BeanDefinitionRegistry registry, @Nullable Object source) {

	// 省略部分代码...

	Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

	// 注册 AutowiredAnnotationBeanPostProcessor,这个bean的后置处理器用来处理@Autowired的注入 
	// 处理 @Autowired 以及 @Value 注解
	if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
	}

	// 注册CommonAnnotationBeanPostProcessor,用来处理如@Resource等符合JSR-250规范的注解
	// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
	if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
	}

	// 省略部分代码

	return beanDefs;
}

在这个方法中可以看到会注册 AutowiredAnnotationBeanPostProcessor 和 CommonAnnotationBeanPostProcessor 两个处理器

然后在 Spring 应用上下文刷新阶段会将其初始化并添加至 AbstractBeanFactory 的 beanPostProcessors 集合中

当一个 Bean 被构建时,核心包括两个基本步骤:
1、执行 AbstractAutowireCapableBeanFactory#createBeanInstance 方法:通过构造器反射构造出这个 Bean
2、执行 AbstractAutowireCapableBeanFactory#populate 方法:填充(即设置)这个 Bean

// Invoke factory processors registered as beans in the context.
AbstractApplicationContext::refresh()
 
AbstractAutowireCapableBeanFactory::doCreateBean()
                                    populateBean()

在构建appConfig bean时会走到 populateBean方法

/**
	* Populate the bean instance in the given BeanWrapper with the property values
	* from the bean definition.
	* @param beanName the name of the bean
	* @param mbd the bean definition for the bean
	* @param bw the BeanWrapper with bean instance
	*/
@SuppressWarnings("deprecation")  // for postProcessPropertyValues
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {

	//省略部分非关键代码

	if (hasInstAwareBpps) {
		if (pvs == null) {
			pvs = mbd.getPropertyValues();
		}
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				// 执行后置处理器,填充属性,完成自动装配
				// 在这里会调用到AutowiredAnnotationBeanPostProcessor
				PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
				if (pvsToUse == null) {
					if (filteredPds == null) {
						filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
					}
					pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						return;
					}
				}
				pvs = pvsToUse;
			}
		}
	}

	//省略部分非关键代码

}

因为 StudentController 含有标记为 Autowired 的成员属性 dataService,所以会使用到 AutowiredAnnotationBeanPostProcessor(BeanPostProcessor 中的一种)来完成“装配”过程:找出合适的 DataService 的 bean 并设置给 StudentController#dataService。
这个装配过程,又可以细分为两个步骤:
1、AutowiredAnnotationBeanPostProcessor::postProcessProperties

public PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
	// 解析出bean中带有@Autowired注解、@Inject和@Value注解的属性和方法
	// 对于本文的demo而言,在此处就会解析出OrderServiceImpl类上的userService属性
	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;
}

2、根据依赖信息寻找出依赖并完成注入,以字段注入为例 AutowiredFieldElement#inject
备注 AutowiredFieldElement 是 AutowiredAnnotationBeanPostProcessor 的一个内部类

@Override
@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 {
			// 寻找“依赖”,desc为"xxxService"的DependencyDescriptor
			value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
		}
		catch (BeansException ex) {
			throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
		}
		
	}

}

参考

[1] @Autowired注解的实现原理
[2] 死磕Spring之IoC篇 - @Autowired 等注解的实现原理
[3] 02|Spring Bean 依赖注入常见错误(上)