@Autowired源码分析

AutowiredAnnotationBeanPostProcessor

@Autowired注解的逻辑是由AutowiredAnnotationBeanPostProcessor实现的,AutowiredAnnotationBeanPostProcessor不是一个简单的BeanPostProcessor,而是一个实现了多重接口的BeanPostProcessor,它主要实现了以下两个接口:

  • InstantiationAwareBeanPostProcessor:对应postProcessPropertyValues()方法
  • MergedBeanDefinitionPostProcessor:对应findAutowiringMetadata方法

下面我们分别来看看这两个接口的实现是如何完成@Autowired的逻辑的。

作为MergedBeanDefinitionPostProcessor的行为

首先,我们从ApplicationContext体系最核心的refresh()方法说起:

refresh()方法中registerBeanPostProcessors(beanFactory)这一行代码完成了对AutowiredAnnotationBeanPostProcessor的注册,当执行finishBeanFactoryInitialization(beanFactory)方法时,会实例化所有非懒加载的单例Bean,这个过程中会调用AbstractAutowireCapableBeanFactory类的doCreateBean()方法,其中在使用合适的实例化策略实例化完Bean之后,会有下面这么一段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// ...
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;
}
}

// ...
}

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}

applyMergedBeanDefinitionPostProcessors()方法中,会判断当前的BeanPostProcessor是否是MergedBeanDefinitionPostProcessor类型的,如果是的话则调用它的postProcessMergedBeanDefinition()方法(显然,这里会判断为真,因为AutowiredAnnotationBeanPostProcessor实现了MergedBeanDefinitionPostProcessor)。我们再来看看AutowiredAnnotationBeanPostProcessor对该方法的实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if (beanType != null) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
}

private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, PropertyValues pvs) {

String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey); // 先从缓存中找 InjectionMetadata,诸如 @Autowire,@Inject 等
if (InjectionMetadata.needsRefresh(metadata, clazz)) { // 如果找不到,则从这里开始,通过分析 bean,去找到它的 InjectionMetadata
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
try {
metadata = buildAutowiringMetadata(clazz); // 重点关注:去找,并构建其 InjectionMetadata 对象
this.injectionMetadataCache.put(cacheKey, metadata); // 如果找到了,将其放入 injectionMetadataCache 中返回;
}
catch (NoClassDefFoundError err) {
throw new IllegalStateException("Failed to introspect bean class [" + clazz.getName() +
"] for autowiring metadata: could not find class that it depends on", err);
}
}
}
}
return metadata;
}

findAutowiringMetadata()方法先从缓存中判断否已经存在该InjectionMetadata了,如果存在,且无需进行刷新,则返回;如果缓存中不存在(或者存在但需要刷新),那么就需要去构建一个InjectionMetadata

接下来就是比较核心的部分了,通过buildAutowiringMetadata()方法构建InjectionMetadata对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
Class<?> targetClass = clazz;

do {
final LinkedList<InjectionMetadata.InjectedElement> currElements =
new LinkedList<InjectionMetadata.InjectedElement>();
// 1. 通过反射从 targetClass 的 field 中去找注解
ReflectionUtils.doWithLocalFields(targetClass, new ReflectionUtils.FieldCallback() {
@Override
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
AnnotationAttributes ann = findAutowiredAnnotation(field); // 是否存在 @Autowired
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static fields: " + field);
}
return; // 如果当前处理的属性是静态属性,则直接返回
}
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
}
});
// 2. 通过反射从 targetClass 的 method 中去找注解
ReflectionUtils.doWithLocalMethods(targetClass, new ReflectionUtils.MethodCallback() {
@Override
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
// 上述代码处理 bridged method 相关情况;可忽略;
AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod); // 是否存在 @Autowired
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static methods: " + method);
}
return; // 如果方法是静态的,则直接返回;
}
if (method.getParameterTypes().length == 0) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation should only be used on methods with parameters: " +
method); // 警告,方法参数长度为 0
}
}
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 new InjectionMetadata(clazz, elements);
}

该方法分为两部分,通过工具类ReflectionUtils分别从当前Bean实例的fieldsmethods中去查找@Autowired注解:

  1. fields@Autowired注解,若找到,则创建AutowiredFieldElement实例,并放入currElements队列中
  2. methods中找@Autowired注解,若找到,则创建AutowiredMethodElement实例,并放入currElements队列中
  3. 最后,通过Bean的Class对象和curreElements构建InjectionMetadata实例并返回

此时,将构建好的InjectionMetadata加入缓存injectionMetadataCache中并返回。

作为InstantiationAwareBeanPostProcessor的行为

同样,在doCreateBean()方法中执行populateBean()方法填充属性时,populateBean()方法中有如下一段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}

PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); // 重点关注这一行
if (pvs == null) {
return;
}
}
}
}

其中,pvs = ibp.postProcessPropertyValues()这行代码调用了InstantiationAwareBeanPostProcessor的接口方法,继续跟进去看。

1
2
3
4
5
6
7
8
9
10
11
12
13
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
// <1>
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
// <2>
metadata.inject(bean, beanName, pvs);
} catch (BeanCreationException ex) {
throw ex;
} catch (Throwable ex) {
// ...
}
return pvs;
}

在刚实例化完Bean之后,作为MergedBeanDefinitionPostProcessor,已经调用过findAutowiringMetadata()方法,即从当前Bean对象中的属性和方法中找到了@Autowired注解,并将它们封装成了InjectionMetadata放入了缓存当中,因此,此处直接从缓存中就可以获取到该Bean对应的InjectMetadata。接下来就是通过InjectMetadata进行注入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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);
}
element.inject(target, beanName, pvs); // 重点关注
}
}
}

protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
throws Throwable {

if (this.isField) {
Field field = (Field) this.member;
ReflectionUtils.makeAccessible(field);
field.set(target, getResourceToInject(target, requestingBeanName)); // 重点关注
} else {
if (checkPropertySkipping(pvs)) {
return;
}
try {
Method method = (Method) this.member;
ReflectionUtils.makeAccessible(method);
method.invoke(target, getResourceToInject(target, requestingBeanName)); // 重点关注
} catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}

由于InjectionMetadata对象本身包含了一系列的AutowiredFieldElementAutowiredMethodElement,所以这里迭代InjectedElement并依次处理它们,而处理的逻辑都在inject()这一关键方法中,可以看到最终就是根据是属性还是方法来分别使用反射注入,并且对于方法而言,该方法会被调用。

参考资料