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
27protected 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
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
61private 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() {
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() {
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实例的fields
和methods
中去查找@Autowired
注解:
- 从
fields
找@Autowired
注解,若找到,则创建AutowiredFieldElement
实例,并放入currElements
队列中 - 从
methods
中找@Autowired
注解,若找到,则创建AutowiredMethodElement
实例,并放入currElements
队列中 - 最后,通过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
17if (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 | public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException { |
在刚实例化完Bean之后,作为MergedBeanDefinitionPostProcessor
,已经调用过findAutowiringMetadata()
方法,即从当前Bean对象中的属性和方法中找到了@Autowired
注解,并将它们封装成了InjectionMetadata
放入了缓存当中,因此,此处直接从缓存中就可以获取到该Bean对应的InjectMetadata
。接下来就是通过InjectMetadata
进行注入:
1 | public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { |
由于InjectionMetadata
对象本身包含了一系列的AutowiredFieldElement
和AutowiredMethodElement
,所以这里迭代InjectedElement
并依次处理它们,而处理的逻辑都在inject()
这一关键方法中,可以看到最终就是根据是属性还是方法来分别使用反射注入,并且对于方法而言,该方法会被调用。