@Autowired 源码分析

缘起

@Autowired 注解可以说是几乎每个使用spring的童鞋都要使用的. 那么他的原理是什么呢?

分析

以demo【1】为例,最后起作用的关键类就是

org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(PropertyValues, PropertyDescriptor[], Object, String)

它的源码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {

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

其中第七行源码就是注入bean中去. metadata 包含了要注入的类的信息,比如beanName为bookController的时候,metadata就是AutowiredFieldElement for private com.yfs.service.BookService com.yfs.controller.BookController.bookService.

在这里发生注入的. 其实 不只是 Spring的注入注解 @Autowired, 对于JSR 的 @Inject、@Resource 注解也是在这个AutowiredAnnotationBeanPostProcessor中发生的. 何以为证? 下面的AutowiredAnnotationBeanPostProcessor的构造函数就是证据

1
2
3
4
5
6
7
8
9
10
11
12
13
@SuppressWarnings("unchecked")
public AutowiredAnnotationBeanPostProcessor() {
this.autowiredAnnotationTypes.add(Autowired.class);
this.autowiredAnnotationTypes.add(Value.class);
try {
this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
logger.info("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}

DEMO

【1】https://github.com/yfsyfs/backend/tree/master/spring-annotation-autowired-qualified-primary