@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面試題:請談談對ThreadLocal的理解?
Java面試題:為什麼HashMap不建議使用物件作為Key?
Java面試題:你知道Spring的IOC嗎?那麼,它為什麼這麼重要呢?
Java面試題:執行緒池內“鬧情緒”的執行緒,怎麼辦?
Java面試題:Spring Bean執行緒安全?別擔心,只要你不寫併發程式碼就好了!
Java面試題:Spring框架除了IOC和AOP,還有哪些好玩的設計模式?