@Autowired和@Resource到底什麼區別,你明白了嗎?
阿粉相信,大家做 Java 開發的,肯定對於 Spring 是非常熟悉的,而且面試的時候,也相信大家能夠非常輕易的知道這個所有的關於 Spring 的面試題,比如 Spring 的注入什麼的。也肯定會被問到 @Autowired 和 @Resource 到底用哪個比較適合,今天阿粉就來講講這個注入的註解是個什麼區別。
@Autowired
@Autowired顧名思義,就是自動裝配,而它的作用是為了消除程式碼Java程式碼裡面的 getter/setter 與 bean 屬性中的 property 。
當然,getter看個人需求,如果私有屬性需要對外提供的話,應當予以保留。
也有很多面試官喜歡詢問,Spring 的自動裝配你瞭解麼?其實問的也是這個註解,而這個註解中有幾個屬性,需要大家知道。
- no
預設值,表示不使用自動裝配,Bean 依賴必須通過 ref 元素定義。
- byName
根據 Property 的 name 自動裝配,如果一個 Bean 的 name 和另一個 Bean 中的 Property 的 name 相同,則自動裝配這個 Bean 到 Property 中。(表示按屬性名稱自動裝配,XML 檔案中 Bean 的 id 必須與類中的屬性名稱相同)
- byType
根據 Property 的資料型別(Type)自動裝配,如果一個 Bean 的資料型別相容另一個 Bean 中 Property 的資料型別,則自動裝配。(XML 檔案中 Bean 的 id 與類中的屬性名稱可以不同,但必須只有一個型別的 Bean。)
- constructor
類似於 byType,根據構造方法引數的資料型別,進行 byType 模式的自動裝配。(類中建構函式的引數必須在配置檔案中有相同的型別)
- autodetect(3.0版本不支援)
如果 Bean 中有預設的構造方法,則用 constructor 模式,否則用 byType 模式。
其實這些引數都指明瞭一件事情,這個 @Autowired 的註解,就是根據 type 也就是型別來進行裝配,與之而來的就是 @Resource 他又是什麼呢?
@Resource
官方描述為,一般用在類屬性或者setter方法上宣告屬性需要自動裝配。
如果在Resource註解中指定了bean的名稱,則Spring會只按註解中的bame屬性查詢合適物件,然後進行裝配。如果註解中沒有指定名稱,先按類屬性的變數名查詢,如果還是未找到,則按型別進行查詢。
它的內部也有屬性:
- name
定義了name屬性的值, 就只按照name值匹配,使用byName的自動注入策略
- type
定義了type屬性的值, 就只按照type值匹配,使用byType的自動注入策略
如果你不指定的話,他自己會預設使用反射機制,使用byName自動注入策略。
那麼面試官的問題就來了,@Autowired 和 @Resource 的區別在哪呢?什麼時候選擇用什麼才合適呢?
@Autowired 和 @Resource 的區別
1.包就不一樣
@Autowired 是Spring提供的。
@Resource 是J2EE提供的。也就是Java規範的。
2.裝配的預設型別不一樣
@Autowired只按type裝配。
@Resource預設是按name裝配。
@Autowired預設按型別裝配,預設情況下必須要求依賴物件存在,如果要允許null值,可以設定它的required屬性為false。
如果想使用名稱裝配可以結合@Qualifier註解進行使用。
而預設按照名稱進行裝配,名稱可以通過name屬性進行指定,如果沒有指定name屬性,當註解寫在欄位上時,預設取欄位名進行名稱查詢。
如果註解寫在setter方法上預設取屬性名進行裝配。當找不到與名稱匹配的bean時才按照型別進行裝配。但是需要注意的是,如果name屬性一旦指定,就只會按照名稱進行裝配。
那麼我們選擇哪一種最好呢?
其實大家在開發的時候,有沒有注意到一個地方,就是 IDEA 有時候還會在 @Autowired 註解上面Field injection is not recommended (欄位注入是不被推薦的)這個警告,雖然並不屬於報錯,但是確實是警告的存在。但是 @Resource 就不會呢?
其實有很多人也說不上來為啥,阿粉個人感覺,@Autowired是Spring提供的,它是特定IoC提供的特定註解,這就導致了應用與框架的強繫結,一旦換用了其他的IoC框架,是不能夠支援注入的。
而 @Resource是 Java 自己提供的,它是Java標準,我們使用的IoC容器應當去相容它,這樣即使更換容器,也可以正常工作。
那麼為什麼還有這麼多的人使用的都是 @Autowired 註解呢?
那就只有兩個字了,簡單,使用構造器或者setter注入需要寫更多業務無關的程式碼,十分麻煩,而欄位注入大幅簡化了它們。並且絕大多數情況下業務程式碼和框架就是強繫結的,完全鬆耦合只是一件理想上的事,犧牲了敏捷度去過度追求鬆耦合反而得不償失。
所以,你知道他們的區別是什麼了麼?
- Spring中實現非同步呼叫的方式有哪些?
- 帶引數的全型別 Python 裝飾器
- 整理了幾個Python正則表示式,拿走就能用!
- SOLID:開閉原則Go程式碼實戰
- React中如何引入CSS呢
- 一個新視角:前端框架們都卷錯方向了?
- 編碼中的Adapter,不僅是一種設計模式,更是一種架構理念與解決方案
- 手寫程式語言-遞迴函式是如何實現的?
- 一文搞懂模糊匹配:定義、過程與技術
- 新來個阿里 P7,僅花 2 小時,做出一個多執行緒永動任務,看完直接跪了
- Puzzlescript,一種開發H5益智遊戲的引擎
- @Autowired和@Resource到底什麼區別,你明白了嗎?
- CSS transition 小技巧!如何保留 hover 的狀態?
- React如此受歡迎離不開這4個主要原則
- LeCun再炮轟Marcus: 他是心理學家,不是搞AI的
- Java保證執行緒安全的方式有哪些?
- 19個殺手級 JavaScript 單行程式碼,讓你看起來像專業人士
- Python 的"self"引數是什麼?
- 別整一坨 CSS 程式碼了,試試這幾個實用函式
- 再有人問你什麼是MVCC,就把這篇文章發給他!