在上一篇,我們介紹了@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;
}
進行了真正的反射注入操作