在 Spring 框架中,@Autowired
?和?@Resource
?是兩個常用的注解,用于實現依賴注入。盡管它們都能達到將依賴對象注入到目標 bean 的目的,但在細節上存在一些顯著的差異。本文將深入探討這兩個注解的區別,并結合 Spring 源碼進行分析,同時附上源碼的執行流程圖,幫助您更好地理解它們的工作原理。
一、@Autowired 注解
源碼分析
在 Spring 中,@Autowired
?的處理主要在?AutowiredAnnotationBeanPostProcessor
?類中。當 Spring 容器初始化 bean 時,會遍歷 bean 中的屬性,如果發現帶有?@Autowired
?注解的屬性,就會嘗試從容器中獲取對應的 bean 進行注入
代碼入口:
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {/*** 根據當前bean 查找出來所有添加了@AutoWired 屬性的* 根據屬性實例化 一些注入器*/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;}
}
執行流程
- Spring 容器掃描帶有?
@Autowired
?注解的屬性。 - 根據屬性的類型在容器中查找匹配的 bean。
- 如果找到多個相同類型的 bean,再根據屬性名稱進行匹配。
- 將匹配到的 bean 實例注入到目標屬性。
二、@Resource 注解
@Resource
?是 JSR-250 規范定義的注解,既可以按照名稱進行裝配,也可以按照類型進行裝配。
源碼分析
@Resource
?的處理在 Spring 的?CommonAnnotationBeanPostProcessor
?類中。
代碼入口:
public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor implements MergedBeanDefinitionPostProcessor {@Overridepublic PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {/*** 根據當前bean 查找出來所有添加了@Resource 屬性的* 根據屬性實例化 一些注入器*/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;}
}
執行流程
- Spring 容器掃描帶有?
@Resource
注解的屬性。 - 判斷是@Resource注解中有名字,并且根據name在spring容器中找不到對應的bean,那么就按照@AutoWired的注入方式進行注入
- 條件2 不成立的話那么就按照名字獲取一個bean進行注入