1. 程式人生 > 實用技巧 >@Autowired和@Resource得區別

@Autowired和@Resource得區別

由於個人習慣,註解引入物件的時候喜歡使用@Autowired註解,很少使用@Resource。直到有次在工作中使用到模板方法模式時,使用@Autowired時出現了問題。

場景: 兩個需求有可複用的程式碼或者程式碼塊。

//關於類的建立宣告我就不截圖了,下面幾行程式碼就說明下大致結構。

WorkBenchService
AbstractWorkBench implements WorkBenchService
OperationBenchServiceImpl extends AbstractWorkBench implements WorkBenchService
SellWorkBenchServiceImpl extends AbstractWorkBench implements WorkBenchService

WorkBenchService是一個介面,封裝了一些公用介面方法;AbstractWorkBench是一個抽象類,裡面實現了兩個需求可以複用的方法。對於無法複用的,方法體直接返回null,後續的邏輯由各自的業務類(OperationBenchServiceImpl、SellWorkBenchServiceImpl)來實現。進一步體會到了介面和抽象類的好處。

下面來說具體的使用吧。
最初寫法
@Autowired
private WorkBenchService sellWorkBenchService;
是想先去sellWorkBenchService裡面找A方法,如果有,那麼就使用sellWorkBenchService裡面的。如果沒有那麼就使用WorkBenchService的實現類AbstractWorkBench裡面的。經過測試發現會報錯

然後上網找了下原因,才進一步瞭解到
@Autowired是按照型別來匹配的(這個註解是屬業spring的),如果是要按照名字匹配的話,那麼需要和@Qualifier搭配使用@Qualifier("sellWorkBenchService")。
@Resource是按照name的屬性注入的(這個註解屬於J2EE的),如果按照name沒找到的話,那麼再按照bean型別去找。所以後面我就直接使用@Resource的寫法了。

@Autowired預設按型別裝配(這個註解是屬業spring的),預設情況下必須要求依賴物件必須存在,如果要允許null值,可以設定它的required屬性為false,如:@Autowired(required=false) ,如果我們想使用名稱裝配可以結合@Qualifier註解進行使用。

@Resource裝配順序
  如果同時指定了name和type,則從Spring上下文中找到唯一匹配的bean進行裝配,找不到則丟擲異常
  如果指定了name,則從上下文中查詢名稱(id)匹配的bean進行裝配,找不到則丟擲異常
  如果指定了type,則從上下文中找到型別匹配的唯一bean進行裝配,找不到或者找到多個,都會丟擲異常
  如果既沒有指定name,又沒有指定type,則自動按照byName方式進行裝配;如果沒有匹配,則回退為一個原始型別進行匹配,如果匹配則自動裝配;


注意一下:(1)這個name是我們在SellWorkBenchServiceImpl類上面賦值的,@Service("sellWorkBenchService")。或者是@Autowired @Qualifier("sellWorkBenchServiceImpl")這樣也可以,會根據你類名的首字母小寫進行匹配。

(2)使用@Resource註解的時候,若指定了具體的物件名稱的話,例如@Resource(name="baseDao"),則從上下文中查詢名稱(id)匹配的bean進行裝配,找不到則丟擲異常。

最後也是成功的解決了問題,自己平時也是喜歡封裝一些方法。這樣以後好複用,也好改,看上去也舒服。

附上當時參考的連線:https://blog.csdn.net/weixin_33797791/article/details/91933290