死磕Spring系列:@Autowired工作原理

14 篇文章 5 订阅

1. 前言

本文需要有对SpringBean加载流程的知识基础,如果需要在温习一遍的,可以先阅读博文《死磕Spring系列:从源码理解SpringBean生命周期》。

2. @Autowired

@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;

}

从Autowired的源码中可以得到以下几个信息:
1)可以标注在构造器、方法、参数、字段、注解上。
2)仅有一个required参数,默认为true。

2.1 常用注入方式

2.1.1 setter注入

@Autowired
public void setPerson(Person person) {
  this.person = person;
}

2.1.2 构造器注入

public class Person {
    @Autowired
	public Person (Address address) {
    	this.address = address;
    }
}

2.1.3 字段注入

@Autowired
private Person person;

了解其使用方法之后,从源码中来分析其自动注入的原理。

3. AbstractAutowireCapableBeanFactory

3.1 doCreateBean

在SpringBean创建过程中,会调用到AbstractAutowireCapableBeanFactory类的doCreateBean方法。其中有一段处理逻辑:

// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
	if (!mbd.postProcessed) {
		try {
			applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Post-processing of merged bean definition failed", ex);
		}
		mbd.postProcessed = true;
	}
}

目的是为了执行所有MergedBeanDefinitionPostProcessor中的postProcessMergedBeanDefinition方法。

4. AutowiredAnnotationBeanPostProcessor

其中,AutowiredAnnotationBeanPostProcessor类是MergedBeanDefinitionPostProcessor的实现类,其在AbstractApplicationContextrefresh方法中被添加到beanFactorybeanPostProcessors列表。
AutowiredAnnotationBeanPostProcessor类中被调用的postProcessMergedBeanDefinition方法源码如下:

@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
	InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
	metadata.checkConfigMembers(beanDefinition);
}

功能:
1)获取被@Autowired注解修饰的属性元数据。
2)检查并获取合格的配置Member。此处的Member是反射中的一个类,可以描述一个字段、一个方法、一个构造器的识别信息。

4.1 findAutowiringMetadata

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);
				}
				metadata = buildAutowiringMetadata(clazz);
				this.injectionMetadataCache.put(cacheKey, metadata);
			}
		}
	}
	return metadata;
}

这个方法是用了Map作为缓存的,缓存的key为beanName或者class的name。其中生成元数据的方法为buildAutowiringMetadata

4.2 buildAutowiringMetadata

private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
	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<>();

		ReflectionUtils.doWithLocalFields(targetClass, field -> {
			MergedAnnotation<?> ann = findAutowiredAnnotation(field);
			if (ann != null) {
				if (Modifier.isStatic(field.getModifiers())) {
					if (logger.isInfoEnabled()) {
						logger.info("Autowired annotation is not supported on static fields: " + field);
					}
					return;
				}
				boolean required = determineRequiredStatus(ann);
				currElements.add(new AutowiredFieldElement(field, required));
			}
		});

		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);
				currElements.add(new AutowiredMethodElement(method, required, pd));
			}
		});

		elements.addAll(0, currElements);
		targetClass = targetClass.getSuperclass();
	}
	while (targetClass != null && targetClass != Object.class);

	return InjectionMetadata.forElements(elements, clazz);
}

此方法的主要功能为:
1)扫描该类所有声明的字段,过滤出其中被@Autowired或@Value修饰的字段,如果字段是static类型,则打印日志且return。获取注解中的required属性,缺省为true。将Fieldrequired封装为AutowiredFieldElement类型。
2)扫描该类所有声明的方法,过滤出其中被@Autowired或@Value修饰的方法,如果方法是static类型,则打印日志且return。如果方法没有参数,则打印日志。获取注解中的required属性,缺省为true。将Methodrequired、和其对应的setter或者getter方法封装成AutowiredMethodElement
3)当前指定class下的AutowiredFieldElementAutowiredMethodElement都会被添加到List<InjectionMetadata.InjectedElement>中,此过程是一个循环,会依次对class的superclass(父类)进行操作。最终将所有数据生成一个InjectionMetadata

4.3 checkConfigMembers

public void checkConfigMembers(RootBeanDefinition beanDefinition) {
	Set<InjectedElement> checkedElements = new LinkedHashSet<>(this.injectedElements.size());
	for (InjectedElement element : this.injectedElements) {
		Member member = element.getMember();
		if (!beanDefinition.isExternallyManagedConfigMember(member)) {
			beanDefinition.registerExternallyManagedConfigMember(member);
			checkedElements.add(element);
		}
	}
	this.checkedElements = checkedElements;
}

添加MemberbeanDefinitionexternallyManagedConfigMembers变量。
通过AutowiredAnnotationBeanPostProcessor类的处理,我们获取到了类中被@Autowired修饰的字段和方法的信息,以便于后续调用。

5. AbstractAutowireCapableBeanFactory

5.1 populateBean

回到这个类中,在doCreateBean方法中,执行完applyMergedBeanDefinitionPostProcessors方法后,执行了populateBean方法。调用步骤如下:

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
    ......
	applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
    ......
    populateBean(beanName, mbd, instanceWrapper);
    ......
}

populateBean主要功能是初始化类中所有属性的值,其中就包括了被@Autowired修饰的需要自动注入的部分。

	/**
	 * 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 (bw == null) {
			if (mbd.hasPropertyValues()) {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
			}
			else {
				// Skip property population phase for null instance.
				return;
			}
		}

		// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
		// state of the bean before properties are set. This can be used, for example,
		// to support styles of field injection.
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
				if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					return;
				}
			}
		}

		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

		int resolvedAutowireMode = mbd.getResolvedAutowireMode();
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			// Add property values based on autowire by name if applicable.
			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}
			// Add property values based on autowire by type if applicable.
			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}
			pvs = newPvs;
		}

		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

		PropertyDescriptor[] filteredPds = null;
		if (hasInstAwareBpps) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
				PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
				if (pvsToUse == null) {
					if (filteredPds == null) {
						filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
					}
					pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						return;
					}
				}
				pvs = pvsToUse;
			}
		}
		if (needsDepCheck) {
			if (filteredPds == null) {
				filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			}
			checkDependencies(beanName, mbd, filteredPds, pvs);
		}

		if (pvs != null) {
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}

上述源码主要逻辑:
1)如果不存在bean实例,但是RootBeanDefinition有属性值,那么直接报错。
2)调用InstantiationAwareBeanPostProcessor类的postProcessAfterInstantiation方法,如果返回false,终止当前方法执行。
3)根据RootBeanDefinition的autowireMode属性调用autowireByNameautowireByType方法,然后将属性名称和值放入PropertyValues对象中。
4)调用InstantiationAwareBeanPostProcessor类的postProcessProperties方法,其中AutowiredAnnotationBeanPostProcessor类的postProcessProperties会将InjectionMetadata中的AutowiredFieldElementAutowiredMethodElement调用inject方法进行逐个解析,并将值通过反射设置给bean。
5)将PropertyValues处理后的值赋给BeanWrapper
至此,我们的bean里面所有需要自动注入的属性都已经被填充值了。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值