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
的实现类,其在AbstractApplicationContext
的refresh方法中被添加到beanFactory的beanPostProcessors列表。
在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。将Field和required封装为AutowiredFieldElement
类型。
2)扫描该类所有声明的方法,过滤出其中被@Autowired或@Value修饰的方法,如果方法是static类型,则打印日志且return。如果方法没有参数,则打印日志。获取注解中的required属性,缺省为true。将Method、required、和其对应的setter或者getter方法封装成AutowiredMethodElement
。
3)当前指定class下的AutowiredFieldElement
和AutowiredMethodElement
都会被添加到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;
}
添加Member
到beanDefinition的externallyManagedConfigMembers变量。
通过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属性调用autowireByName或autowireByType方法,然后将属性名称和值放入PropertyValues
对象中。
4)调用InstantiationAwareBeanPostProcessor
类的postProcessProperties方法,其中AutowiredAnnotationBeanPostProcessor
类的postProcessProperties会将InjectionMetadata
中的AutowiredFieldElement
、AutowiredMethodElement
调用inject方法进行逐个解析,并将值通过反射设置给bean。
5)将PropertyValues
处理后的值赋给BeanWrapper
。
至此,我们的bean里面所有需要自动注入的属性都已经被填充值了。