@Autowired注解原理


1. 用法

可以用@Autowired作用于字段或者方法上,下面代码演示注解作用于字段上:

// 被注入的bean@Servicepublic class AService {public void run(){
        System.out.println("success autowire !");
    }
}复制代码
@RestControllerpublic class HelloController {   @Autowired
   private AService aService;
}复制代码

2. 原理

首先看Autowired源码

/*
 * @author Juergen Hoeller
 * @author Mark Fisher
 * @author Sam Brannen
 * @since 2.5
 * @see AutowiredAnnotationBeanPostProcessor
 * @see Qualifier
 * @see Value
 */
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, 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;

}复制代码

从注释中可以看出,实现类是在AutowiredAnnotationBeanPostProcessor中实现的。并且required属性默认为true,说明运行的时候,被@Autowired注解标记的bean必须存在,否则会报错。大家可以试试将上面示例代码中的类AService去掉@Service注解,在启动准会报错,原因见后面源码分析。

AutowiredAnnotationBeanPostProcessor

public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
		implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
		···
		}复制代码

因为之前我debug过Spring中bean的初始化流程,先贴出总结,以后有时间单独再写一篇。 bean初始化执行顺序:

  1. Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName)------InstantiationAwareBeanPostProcessor
  2. Object postProcessAfterInitialization(Object bean, String beanName) ------BeanPostProcessor
  3. void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName)------MergedBeanDefinitionPostProcessor
  4. boolean postProcessAfterInstantiation(Object bean, String beanName)------InstantiationAwareBeanPostProcessor
  5. PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)------InstantiationAwareBeanPostProcessor
  6. void invokeAwareMethods(String beanName, Object bean)
  7. Object postProcessBeforeInitialization(Object bean, String beanName) ------BeanPostProcessor
  8. invokeInitMethods
    1. 先调用实现了InitializingBean接口的afterPropertiesSet()方法
    2. 调用initMethod()方法
  9. postProcessAfterInitialization ------BeanPostProcessor

所以,这里的AutowiredAnnotationBeanPostProcessor中方法执行前后顺序是

  1. org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
  2. org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessProperties

1. 执行 postProcessMergedBeanDefinition方法

将标注@Autowired注解的字段或者方法存入InjectionMetadata对象中

	@Override
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
		InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
		metadata.checkConfigMembers(beanDefinition);
	}
	
	private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
		// Fall back to class name as cache key, for backwards compatibility with custom callers.
		String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
		// Quick check on the concurrent map first, with minimal locking.
		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);
					}
					// 构造InjectionMetadata对象
					metadata = buildAutowiringMetadata(clazz);
					// 将构造好的InjectionMetadata对象放入injectionMetadataCache缓存中
					this.injectionMetadataCache.put(cacheKey, metadata);
				}
			}
		}
		return metadata;
	}
	
	private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
	    // 判断该类是否携带@Autowired或者@Value(在类型,方法或字段上)
		if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
			return InjectionMetadata.EMPTY;
		}

		List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
		Class<?> targetClass = clazz;

		do {
			final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
            
            // 遍历该类所有字段是否带有@Autowired或者@Value
			ReflectionUtils.doWithLocalFields(targetClass, field -> {
				MergedAnnotation<?> ann = findAutowiredAnnotation(field);
				if (ann != null) {
				    // 字段不能用static修饰,否则注入不了
					if (Modifier.isStatic(field.getModifiers())) {
						if (logger.isInfoEnabled()) {
							logger.info("Autowired annotation is not supported on static fields: " + field);
						}
						return;
					}
					// 获取@Autowired中的属性required,默认为true
					boolean required = determineRequiredStatus(ann);
					// 创建一个AutowiredFieldElement封装字段信息以及required值
					currElements.add(new AutowiredFieldElement(field, required));
				}
			});

            // 遍历该类所有方法是否带有@Autowired或者@Value
			ReflectionUtils.doWithLocalMethods(targetClass, method -> {
				Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
				if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
					return;
				}
				MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
				if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
					if (Modifier.isStatic(method.getModifiers())) {
						if (logger.isInfoEnabled()) {
							logger.info("Autowired annotation is not supported on static methods: " + method);
						}
						return;
					}
					if (method.getParameterCount() == 0) {
						if (logger.isInfoEnabled()) {
							logger.info("Autowired annotation should only be used on methods with parameters: " +
									method);
						}
					}
					boolean required = determineRequiredStatus(ann);
					PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
					// 创建一个AutowiredMethodElement封装字段信息以及required值
					currElements.add(new AutowiredMethodElement(method, required, pd));
				}
			});

			elements.addAll(0, currElements);
			//迭代,继续遍历父类
			targetClass = targetClass.getSuperclass();
		}
		while (targetClass != null && targetClass != Object.class);

        // 封装成InjectionMetadata对象
		return InjectionMetadata.forElements(elements, clazz);
	}复制代码

2. 执行 postProcessPropertyValues 方法

    @Override
	public PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
        //从缓存中injectionMetadataCache取出InjectionMetadata对象
		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;
	}复制代码

然后进入到 org.springframework.beans.factory.annotation.InjectionMetadata#inject方法

	public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
		Collection<InjectedElement> checkedElements = this.checkedElements;
		Collection<InjectedElement> elementsToIterate =
				(checkedElements != null ? checkedElements : this.injectedElements);
		if (!elementsToIterate.isEmpty()) {
			for (InjectedElement element : elementsToIterate) {
				if (logger.isDebugEnabled()) {
					logger.debug("Processing injected element of bean '" + beanName + "': " + element);
				}
				// 这里因为AutowiredAnnotationBeanPostProcessor重写了InjectedElement
				element.inject(target, beanName, pvs);
			}
		}
	}复制代码

在AutowiredAnnotationBeanPostProcessor中重写了InjectedElement,分别有AutowiredMethodElement与AutowiredFieldElement。 因为我们例子中是在字段上标注的注解,所以我们这里以AutowiredFieldElement举例:

private class AutowiredFieldElement extends InjectionMetadata.InjectedElement {@Overrideprotected 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 {// 获取被@Autowired标注的bean ‘Aservice’
			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;
			}
		}
	}	// 反射给属性赋值if (value != null) {
		ReflectionUtils.makeAccessible(field);
		field.set(bean, value);
	}
}复制代码

一路追踪.DefaultListableBeanFactory#resolveDependency代码 DefaultListableBeanFactory#doResolveDependency

public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
    ···
	Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
	// 如果matchingBeans找不到对应的bean则返回null
	if (matchingBeans.isEmpty()) {
	    // required默认为true,那么这里会抛出NoSuchBeanDefinitionException异常
		if (isRequired(descriptor)) {
			raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
		}
		return null;
	}
	···下面实例化bean代码省略
	// 不为null就根据matchingBeans获取对应的bean实例
}

	private void raiseNoMatchingBeanFound(
			Class<?> type, ResolvableType resolvableType, DependencyDescriptor descriptor) throws BeansException {

		checkBeanNotOfRequiredType(type, descriptor);

		throw new NoSuchBeanDefinitionException(resolvableType,
				"expected at least 1 bean which qualifies as autowire candidate. " +
				"Dependency annotations: " + ObjectUtils.nullSafeToString(descriptor.getAnnotations()));
	}复制代码

DefaultListableBeanFactory#findAutowireCandidates 终于发现了关键代码

protected Map<String, Object> findAutowireCandidates(			@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {

		String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(				this, requiredType, true, descriptor.isEager());
		...复制代码

如果默认的@Autowired,里面required为true,那么这里如果将类'Aservice'上的注解@Service去掉,那么在上面这行代码中找不到对应的beanName,就会返回null。 找到的话,就正常获取bean实例返回,最后通过反射赋值。

3. 总结

其实@Resource注解源码跟@Autowired实现类似,实现类是在CommonAnnotationBeanPostProcessor中,大家可以尝试自己看一下。 还有这篇文章中,AutowiredAnnotationBeanPostProcessor该类不仅仅处理了@Autowired注解,其实还有个@Value注解,这里我没写,下次有时间在分析。

最后,@Autowired注解作用在字段上,其实就是通过AutowiredFiledElement中的field.set(bean, valu)注入,作用在方法上,就是通过AutowiredMethodElement中的method.invoke(bean, arguments)。