你可能使用了Spring最不推薦的註解方式
前言
使用Spring框架最核心的兩個功能就是IOC和AOP。IOC也就是控制反轉,我們將類的實例化、依賴關系等都交由Spring來處理,以達到解耦合、利用復用、利於測試、設計出更優良程序的目的。而對用戶來說,操作最對的便是註解。在Spring中提供了三類註解方式,下面我們就逐一分析。最後,你會發現,你最常用、看起來最方便的形式確實最不推薦的一種形式。
常見的註入方式
Field註入
@Controller
public class FooController {
@Autowired
// @Resource
private FooService fooService;
此種註解方式,應用最廣泛:
註入簡單,只需在字段上添加@Autowired或@Resource;
減少大量冗余代碼,美觀;
新增Field時不需要過多代碼修改;
構造函數註入
@Controller
public class FooController {
private final FooService fooService;
private final FooService1 www.michenggw.com fooService1;
@Autowired
public FooController(www.dasheng178.com FooService fooService,FooService1 fooService1) {
this.fooService = fooService;
this.fooService1 = fooService1;
@Controller
public class FooController {
private final FooService fooService;
// 當只有一個參數時可不寫@Autowired
public FooController(FooService www.ysyl157.com fooService) {
this.fooService = fooService;
Spring4.x推薦的註入方式。對比Field註入:
代碼臃腫
新增Field修改麻煩
當Field多余5個時不符合構造方法的基本規範,顯得笨重、臃腫;
setter註入
@Controller
public class FooController {
private FooService fooService;
@Autowired
public void setFooService(FooService fooService) {
this.fooService = fooService;
Spring3.x推薦的註入方式,但並沒有被廣泛應用,當初推薦的理由:
解決了構造器註入的笨重;
可以讓類在之後重新配置或者重新註入。
為什麽Spring4.x推薦構造函數註入
在上面的分析看來,構造函數註入好像並沒有顯現出來它的優勢,但問什麽Spring4.x會推翻之前推薦的setter註入,采用構造函數註入呢?官方的理由匯總如下:
依賴不可變:加入了final來約束修飾Field,這條是很顯然的;
依賴不可為空:在實例化的時候會檢查構造函數參數是否為空,如果為空(未找到改類型的實例對象)則會拋出異常。
單一職責:當使用構造函數註入時,如果參數過多,你會發現當前類的職責過大,需要進行拆分。而使用Field註入時,你並不會意識到此問題。
更利於單元測試:按照其他兩種方式註入,當單元測試時需要初始化整個spring的環境,而采用構造方法註入時,只需要初始化需要的類即可,即可以直接實例化需要的類。
避免IOC容器以外環境調用時潛在的NPE(空指針異常)。
避免循環依賴。
保證返回客戶端(調用)的代碼的時候是完全初始化的狀態。
疑問
如果有大量依賴需要註入,怎麽辦?
如果有大量依賴需要註入說明該類的職責過於復雜,需要遵從單一性原則進行拆分;
其他註入方式是否合理?
存在即合理,根據具體情況可以采用最適合的方式。比如,可以同時使用@Qualifier來達到一些約束限定的目的。也可以使用setter註入和構造函數註入相結合的方式來進行註入。
你可能使用了Spring最不推薦的註解方式