1. Spring常見的注入方式
1.1 Field注入
field即在變數上直接使用注解進行注入,內部使用反射的方式實作注入到field中,
- 優點:代碼簡潔有效,最為開發人員喜歡使用
- 缺點:依賴物件可能為null而報空指標例外,容易出現回圈依賴問題
@Autowired
private GoodsCategoryService goodsCategoryService;
1.2 setter注入
spring 3.x版本中推薦使用的注入方式,通過在set方法上使用注解完成物件注入,
- 優點:選擇性注入,可有可無,依賴不會影響整個專案運行
- 缺點:在物件實體化后,依賴資訊依然可以通過set方法修改,不太好
private GoodsCategoryService goodsCategoryService;
@Autowired
public setGoodsCategoryService(GoodsCategoryService goodsCategoryService){
this.goodsCategoryService = goodsCategoryService;
}
1.3 構造器注入
spring 4.x版本時Spring團隊推薦使用的注入方式,將注解標注在建構式上,物件以引數的形式傳遞,在建構式中完成注入物件的初始化,
- 優點:變數定義使用強制性的顯式注入(final關鍵字保證不可變)、避免空指標和回圈依賴,
- 缺點:在需要注入的依賴較多時,使用構造方法臃腫
private final GoodsCategoryService goodsCategoryService;
@Autowired
public GoodServiceImpl(GoodsCategoryService goodsCategoryService){
this.goodsCategoryService = goodsCategoryService;
}
2. Spring為什么推薦使用構造器注入
Field注入盡管代碼上簡潔有效,但是會帶來一些問題:
- 對于IOC容器以外的環境,除了使用反射來提供它需要的依賴之外,無法復用該實作類
- 不呼叫依賴bean時,不會發現空指標的例外,在運行時呼叫會報例外
- 使用field注入可能會導致回圈依賴,即A里面注入B,B里面又注入A
- 會造成依賴臃腫,職責過多,使用Filed注入時,添加數量不受限制(沒有警告),可能會注入過多的依賴項,違反了單一職責原則,
Setter方法注入是Spring 3.x版本推薦的注入方式,因為setter的方式能用讓類在之后重新配置或者重新注入,但是
- 寫起來比較麻煩,每個依賴都需要一個set方法
- 可以重新配置或注入雖然方便,但是有些依賴需要不可變,使用此種方式產生不確定性
構造器注入是Spring 4.x 版本推薦的注入方式,主要優點有:
- 依賴不可變,使用final定義,保證注入后的不可變
- 依賴不為null,使用建構式傳參的方式,在實體化物件傳參時如果引數為null,則報錯,提前避免了空指標例外
- 在傳參時傳入的是依賴物件,而該物件傳入時會保證物件類已經完成了初始化,也同時保證了物件不為null
- 如果構造器注入時發生了回圈依賴,在專案啟動時就會報錯BeanCurrentlyInCreationException,而Field注入只有在使用時才會報錯
3. @Autowired、@Resource和@Inject的區別
3.1 @Autowired
- @Autowired注解是Spring2.5之后帶入的注解,通過AutowiredAnnotationBeanPostProcessor類實作注入
- @Autowired可以標注在CONSTRUCTOR、METHOD、PARAMETER、FIELD、ANNOTATION_TYPE之上
- @Autowired默認根據bean型別進行自動裝配,byType
- @Autowired注入時如果發現同型別有多個bean,此時需要使用@Qualifier注解來指定bean的name,即byName
- @Autowired注解有屬性required,默認為true,設定為false則表示未找到對應bean時不拋出例外
3.2 @Resource
- @Resource時javax.annotation包下的注解
- @Resource可以標注在TYPE, FIELD, METHOD之上
- @Resource是根據屬性名稱進行自動裝配的,其擁有屬性name,可以根據屬性值指定裝配bean的name
3.3 @Inject
@Inject注解需要匯入javax.inject.Inject包,能實作注入 @Inject可以標注在CONSTRUCTOR、METHOD、FIELD之上 @Inject注解是根據型別自動裝配的,如果需要指定名稱,則需要配合@Named注解
4. 總結
盡管Spring 4.x 推薦使用構造器注入,但是我們仍然可以使用其他方式,且可以使用混合方式注入
- 不可變的注入使用構造器
- 可變可選注入使用setter方法
- 對于多實作的依賴注入時,可以使用Filed注入或者setter方法來指定注入的實作
- 實際使用Field注入的仍然很多,大部分是一些遺留問題,后續新專案可以嘗試盡量避免Field注入
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/335434.html
標籤:其他
