@Autowired是Spring框架提供的註解,@Resource是Java EE 5規範提供的註解。 @Autowired預設按照類型自動裝配,而@Resource預設按照名稱自動裝配。 @Autowired支持@Qualifier註解來指定裝配哪一個具有相同類型的bean,而@Resourc... ...
@Autowired和@Resource都是Java Spring框架中的註解,用於實現依賴註入(DI)和控制反轉(IoC)。
它們的區別主要在以下三個方面:
源頭不同
@Autowired是Spring自帶的註解,而@Resource是JSR 250規範中定義的註解。因此,在使用Spring框架的時候,通常建議使用@Autowired註解。
查找順序不同
在註入Bean時,@Autowired註解的查找順序為:先按類型(byType)匹配,如果有多個Bean符合該類型,則再按照名稱(byName)進行匹配。如果兩種方式都無法唯一確定Bean,則會拋出異常。
偽代碼如下:
public class Person { private Phone phone; @Autowired public void setPhone(Phone phone) { this.phone = phone; } //... } public interface Phone { //... } @Component("apple") public class ApplePhone implements Phone { //... } @Component("huawei") public class HuaweiPhone implements Phone { //... }
在上面的示例中,如果有ApplePhone和HuaweiPhone兩個Bean都實現了Phone介面,那麼當Person類的setPhone方法被調用時,Spring會根據類型匹配到這兩個Bean,但是無法唯一確定,此時會拋出異常。可以通過添加@Qualifier註解來指定具體的Bean:
偽代碼如下:@Autowired @Qualifier("apple") public void setPhone(Phone phone) { this.phone = phone; }
而@Resource註解的查找順序為:先按照名稱(byName)進行匹配,如果無法匹配到Bean,則再按照類型(byType)進行匹配。
偽代碼如下:public class Person { private Phone phone; @Resource(name = "apple") public void setPhone(Phone phone) { this.phone = phone; } //... } @Component("apple") public class ApplePhone implements Phone {...} @Component("huawei") public class HuaweiPhone implements Phone {...}
在上面的示例中,當Person類的setPhone方法被調用時,Spring會先根據名稱查找是否有名稱為"apple"的Bean,如果有,則直接註入;如果沒有,則再根據類型匹配。
適用範圍不同
@Autowired註解可以用於構造器、Setter方法、欄位和方法上,而@Resource註解只能用於欄位和方法上。因此,如果需要在構造器中註入Bean,就必須使用@Autowired註解。綜上所述,建議在使用Spring框架時,儘量使用@Autowired註解。
以下是具體的代碼示例:
public interface Phone { String brand(); } @Component("apple") public class ApplePhone implements Phone { @Override public String brand() { return "Apple"; } } @Component("huawei") public class HuaweiPhone implements Phone { @Override public String brand() { return "Huawei"; } } @Component public class Person { // 使用@Autowired註解進行註入 @Autowired private Phone phone1; // 使用@Resource註解進行註入,指定名稱 @Resource(name = "apple") private Phone phone2; private Phone phone3; public void setPhone3(Phone phone3) { this.phone3 = phone3; } // 使用@Autowired註解和@Qualifier註解進行註入 @Autowired @Qualifier("huawei") public void setPhone4(Phone phone4) { this.phone4 = phone4; } }
在上面的示例中,Person類中有四個屬性需要註入Bean。其中,phone1屬性使用了@Autowired註解,使用預設的查找方式進行註入;phone2屬性使用了@Resource註解,並指定了名稱為"apple"的Bean進行註入;phone3屬性沒有。
總結一下:
-
@Autowired是Spring框架提供的註解,@Resource是Java EE 5規範提供的註解。
-
@Autowired預設按照類型自動裝配,而@Resource預設按照名稱自動裝配。
-
@Autowired支持@Qualifier註解來指定裝配哪一個具有相同類型的bean,而@Resource 預設按照名稱進行註入,如果指定了name或者type屬性,則會按照指定的名稱或者類型來查找對應的Bean實例進行註入。
綜上所述,@Autowired更加靈活,但也更加複雜;@Resource更加簡單、直觀,適用於簡單的場景。
往期面試題:
Java面試題:如果你這樣做,你會後悔的,兩次啟動同一個線程~~~
Java面試題:@PostConstruct、init-method和afterPropertiesSet執行順序?
Java面試題:SimpleDateFormat是線程安全的嗎?使用時應該註意什麼?
Java面試題:細數ThreadLocal大坑,記憶體泄露本可避免
Java面試題:為什麼HashMap不建議使用對象作為Key?
Java面試題:你知道Spring的IOC嗎?那麼,它為什麼這麼重要呢?
Java面試題:Spring Bean線程安全?別擔心,只要你不寫併發代碼就好了!
Java面試題:Spring框架除了IOC和AOP,還有哪些好玩的設計模式?