在上一篇,我们介绍了@Autowired的工作原理,本篇我们依然借用上一篇的例子,来说明@Resource的工作原理
@Component
public class Controller {
@Resource
public Service service;
public void add() {
service.add();
}
}
在例子中,我们只是把@Autowired换成了@Resource,其他都没变,执行的结果都是一样的,那@Resource是怎么被注入的呢?
基本的流程,跟@Autowired是大致相同的。
1. 获取@Resource数据
如果看过@Autowired的分析,@Resource就会非常容易理解,在@Autowired的讲解中,我们提到当执行到AbstractAutowireCapableBeanFactory的doCreateBean方法,会有这面一段代码
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// @Autowired注解在这里注入,@Resource也在这里注入
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
这里允许后置处理来修改bean definition,@AutoWired、@Resource就是后置处理器中的一员,进入applyMergedBeanDefinitionPostProcessors方法,
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
// 当bp为CommonAnnotationBeanPostProcessor时,会进行@Resource的注入
// 当bp为AutowiredAnnotationBeanPostProcessor时,会进行@Autowired的注入
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
当bp为CommonAnnotationBeanPostProcessor时,执行CommonAnnotationBeanPostProcessor类中的postProcessMergedBeanDefinition方法,
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
// 查找被@Resource注解的属性和方法
super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
从这个方法开始,@Resource的获取metadata数据的流程,跟@Autowired差不多就一样了。
2. 注入Resource数据
当程序执行到AbstractAutowireCapableBeanFactory的populateBean方法时,有如下代码
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
// 生命周期 step5 InstantiationAwareBeanPostProcessor.postProcessPropertyValues
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
当beanName为controller时,会进入postProcessProperties方法。
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
try {
metadata.inject(bean, beanName, pvs);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
}
return pvs;
}
进行了真正的反射注入操作