Java中@Autowired和@Resource區(qū)別
@Autowired 和 @Resource 都是 Spring/Spring Boot 項(xiàng)目中,用來(lái)進(jìn)行依賴注入的注解。它們都提供了將依賴對(duì)象注入到當(dāng)前對(duì)象的功能,但二者卻有眾多不同,并且這也是常見(jiàn)的面試題之一,所以我們今天就來(lái)盤(pán)它。 @Autowired 和 @Resource 的區(qū)別主要體現(xiàn)在以下 5 點(diǎn):
- 來(lái)源不同;
- 依賴查找的順序不同;
- 支持的參數(shù)不同;
- 依賴注入的用法不同;
- 編譯器 IDEA 的提示不同。
1.來(lái)源不同
@Autowired 和 @Resource 來(lái)自不同的“父類”,其中 @Autowired 是 Spring 定義的注解,而 @Resource 是 Java 定義的注解,它來(lái)自于 JSR-250(Java 250 規(guī)范提案)。
小知識(shí):JSR 是 Java Specification Requests 的縮寫(xiě),意思是“Java 規(guī)范提案”。任何人都可以提交 JSR 給 Java 官方,但只有最終確定的 JSR,才會(huì)以 JSR-XXX 的格式發(fā)布,如 JSR-250,而被發(fā)布的 JSR 就可以看作是 Java 語(yǔ)言的規(guī)范或標(biāo)準(zhǔn)。
2.依賴查找順序不同
依賴注入的功能,是通過(guò)先在 Spring IoC 容器中查找對(duì)象,再將對(duì)象注入引入到當(dāng)前類中。而查找有分為兩種實(shí)現(xiàn):按名稱(byName)查找或按類型(byType)查找,其中 @Autowired 和 @Resource 都是既使用了名稱查找又使用了類型查找,但二者進(jìn)行查找的順序卻截然相反。
2.1 @Autowired 查找順序
@Autowired 是先根據(jù)類型(byType)查找,如果存在多個(gè) Bean 再根據(jù)名稱(byName)進(jìn)行查找,它的具體查找流程如下:
關(guān)于以上流程,可以通過(guò)查看 Spring 源碼中的 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues 實(shí)現(xiàn)分析得出,源碼執(zhí)行流程如下圖所示:
2.2 @Resource 查找順序
@Resource 是先根據(jù)名稱查找,如果(根據(jù)名稱)查找不到,再根據(jù)類型進(jìn)行查找,它的具體流程如下圖所示:
關(guān)于以上流程可以在 Spring 源碼的 org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessPropertyValues 中分析得出。雖然 @Resource 是 JSR-250 定義的,但是由 Spring 提供了具體實(shí)現(xiàn),它的源碼實(shí)現(xiàn)如下:
2.3 查找順序小結(jié)
由上面的分析可以得出:
- @Autowired 先根據(jù)類型(byType)查找,如果存在多個(gè)(Bean)再根據(jù)名稱(byName)進(jìn)行查找;
- @Resource 先根據(jù)名稱(byName)查找,如果(根據(jù)名稱)查找不到,再根據(jù)類型(byType)進(jìn)行查找。
3.支持的參數(shù)不同
@Autowired 和 @Resource 在使用時(shí)都可以設(shè)置參數(shù),比如給 @Resource 注解設(shè)置 name 和 type 參數(shù),實(shí)現(xiàn)代碼如下:
@Resource(name = "userinfo", type = UserInfo.class) private UserInfo user;
但二者支持的參數(shù)以及參數(shù)的個(gè)數(shù)完全不同,其中 @Autowired 只支持設(shè)置一個(gè) required 的參數(shù),而 @Resource 支持 7 個(gè)參數(shù),支持的參數(shù)如下圖所示:
4.依賴注入的支持不同
@Autowired 和 @Resource 支持依賴注入的用法不同,常見(jiàn)依賴注入有以下 3 種實(shí)現(xiàn):
- 屬性注入
- 構(gòu)造方法注入
- Setter 注入
這 3 種實(shí)現(xiàn)注入的實(shí)現(xiàn)代碼如下。
a) 屬性注入
@RestController public class UserController { // 屬性注入 @Autowired private UserService userService; @RequestMapping("/add") public UserInfo add(String username, String password) { return userService.add(username, password); } }
b) 構(gòu)造方法注入
@RestController public class UserController { // 構(gòu)造方法注入 private UserService userService; @Autowired public UserController(UserService userService) { this.userService = userService; } @RequestMapping("/add") public UserInfo add(String username, String password) { return userService.add(username, password); } }
c) Setter 注入
@RestController public class UserController { // Setter 注入 private UserService userService; @Autowired public void setUserService(UserService userService) { this.userService = userService; } @RequestMapping("/add") public UserInfo add(String username, String password) { return userService.add(username, password); } }
其中, @Autowired 支持屬性注入、構(gòu)造方法注入和 Setter 注入,而 @Resource 只支持屬性注入和 Setter 注入,當(dāng)使用 @Resource 實(shí)現(xiàn)構(gòu)造方法注入時(shí)就會(huì)提示以下錯(cuò)誤:
5.編譯器提示不同
當(dāng)使用 IDEA 專業(yè)版在編寫(xiě)依賴注入的代碼時(shí),如果注入的是 Mapper 對(duì)象,那么使用 @Autowired 編譯器會(huì)提示報(bào)錯(cuò)信息,報(bào)錯(cuò)內(nèi)容如下圖所示:
雖然 IDEA 會(huì)出現(xiàn)報(bào)錯(cuò)信息,但程序是可以正常執(zhí)行的。 然后,我們?cè)?strong>將依賴注入的注解更改為 @Resource 就不會(huì)出現(xiàn)報(bào)錯(cuò)信息了,具體實(shí)現(xiàn)如下:
總結(jié)
@Autowired 和 @Resource 都是用來(lái)實(shí)現(xiàn)依賴注入的注解(在 Spring/Spring Boot 項(xiàng)目中),但二者卻有著 5 點(diǎn)不同:
- 來(lái)源不同:@Autowired 來(lái)自 Spring 框架,而 @Resource 來(lái)自于(Java)JSR-250;
- 依賴查找的順序不同:@Autowired 先根據(jù)類型再根據(jù)名稱查詢,而 @Resource 先根據(jù)名稱再根據(jù)類型查詢;
- 支持的參數(shù)不同:@Autowired 只支持設(shè)置 1 個(gè)參數(shù),而 @Resource 支持設(shè)置 7 個(gè)參數(shù);
- 依賴注入的用法支持不同:@Autowired 既支持構(gòu)造方法注入,又支持屬性注入和 Setter 注入,而 @Resource 只支持屬性注入和 Setter 注入;
- 編譯器 IDEA 的提示不同:當(dāng)注入 Mapper 對(duì)象時(shí),使用 @Autowired 注解編譯器會(huì)提示錯(cuò)誤,而使用 @Resource 注解則不會(huì)提示錯(cuò)誤。
到此這篇關(guān)于Java中@Autowired和@Resource區(qū)別的文章就介紹到這了,更多相關(guān)Java @Autowired和@Resource內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring中的事務(wù)控制知識(shí)總結(jié)
我們講了轉(zhuǎn)賬方法存在著事務(wù)問(wèn)題,當(dāng)在業(yè)務(wù)層方法更新轉(zhuǎn)入賬戶時(shí)發(fā)現(xiàn)異常,更新收款方賬戶則會(huì)出錯(cuò).當(dāng)時(shí)是通過(guò)自定義事務(wù)管理器進(jìn)行整體事務(wù)的處理.其實(shí)Spring 提供了業(yè)務(wù)層的事務(wù)處理解決方案,并且 Spring 的事務(wù)控制都是基于 AOP 的,需要的朋友可以參考下2021-06-06IDEA 2020.1 版自動(dòng)導(dǎo)入MAVEN依賴的方法(新版MAVEN無(wú)法自動(dòng)導(dǎo)入/更新POM依賴、MAVEN設(shè)置自動(dòng)更
這篇文章主要介紹了IDEA 2020.1 版自動(dòng)導(dǎo)入MAVEN依賴的方法(新版MAVEN無(wú)法自動(dòng)導(dǎo)入/更新POM依賴、MAVEN設(shè)置自動(dòng)更新、自動(dòng)更新快捷鍵),需要的朋友可以參考下2020-08-08Java之maven打完jar包之后將jar包放到指定位置匯總
這篇文章主要介紹了Java之maven打完jar包之后將jar包放到指定位置匯總,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04spring?boot常見(jiàn)get?、post請(qǐng)求參數(shù)處理、參數(shù)注解校驗(yàn)、參數(shù)自定義注解校驗(yàn)問(wèn)題解析
這篇文章主要介紹了spring?boot常見(jiàn)get?、post請(qǐng)求參數(shù)處理、參數(shù)注解校驗(yàn)、參數(shù)自定義注解校驗(yàn),本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-09-09SpringBoot中使用spring-retry 解決失敗重試調(diào)用
本文主要介紹了SpringBoot中使用spring-retry 解決失敗重試調(diào)用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07SpringBoot+MyBatis整合ClickHouse實(shí)踐記錄
本文介紹了如何使用SpringBoot、MyBatis和ClickHouse整合,包括添加依賴、配置數(shù)據(jù)源、創(chuàng)建實(shí)體類、Mapper接口、服務(wù)層和控制器的步驟,通過(guò)這些步驟,可以使Java應(yīng)用程序高效地與ClickHouse數(shù)據(jù)庫(kù)進(jìn)行交互,感興趣的朋友跟隨小編一起看看吧2024-12-12Java線程池ForkJoinPool(工作竊取算法)的使用
Fork就是把一個(gè)大任務(wù)切分為若干個(gè)子任務(wù)并行地執(zhí)行,Join就是合并這些子任務(wù)的執(zhí)行結(jié)果,最后得到這個(gè)大任務(wù)的結(jié)果。Fork/Join?框架使用的是工作竊取算法。本文主要介紹了ForkJoinPool的使用,需要的可以參考一下2022-11-11