你還在用@Autowired和@Resource?
theme: juejin
我正在參加「掘金·啟航計劃」
首先我不承認我的題目有虛假、誇大和引流的嫌疑,直接進入正題。
先透個底:我們在類上使用 Lombok的@RequiredArgsConstructor 註解來替代類中的多處@Autowired和@Resource
。
依賴注入
先回顧一下Spring的3種依賴注入。
- 屬性注入
``` public class SysUserController extends BaseController { @Autowired private ISysUserService userService;
@Resource
private ISysRoleService roleService;
} ```
@Autowired預設按型別裝配,@Resource預設按名稱裝配,當找不到與名稱匹配的bean時,才會按型別裝配。
而@Qualifier和Autowired配合使用,指定bean的名稱,也可以做到按名稱裝配。
IDEA中直接在變數上使用 @Autowired會發現警告提示:Field injection is not recommended
。
原因是官方建議我們使用構造器注入方式,這種方式存在明顯的弊端,比如:注入物件不能用final修飾、無法發現NullPointException的存在。
- 構造器注入
``` public class SysUserController extends BaseController {
private final ISysUserService userService;
private final ISysRoleService roleService;
public SysUserController(ISysUserService userService, ISysRoleService roleService) {
this.userService = userService;
this.roleService = roleService;
}
} ```
構造器依賴注入通過容器觸發一個類的構造器來實現的,通過強制指明依賴注入來保證這個類的執行,防止NullPointerException
;
Spring官方推薦使用構造器注入不僅是因為這種情況下成員屬性可以使用final關鍵字修飾,更關鍵的一點是能夠避免迴圈依賴,如果存在迴圈依賴,Spring專案啟動的時候就會報錯。
為什麼說是避免而不是解決呢?
因為構造器注入是通過構造方法來生成物件,其必須要先獲取屬性,才能生成呼叫構造方法進行例項化,這種情況的迴圈依賴是無法解決的。
下面通過一張圖來看下A、B倆相互依賴的物件注入方式不同時Spring能否解決迴圈依賴的情況:
構造器注入方式解決迴圈依賴:
1.程式碼重構
[email protected]註解
3.改用屬性注入
建議檢視:zhuanlan.zhihu.com
- Setter注入
``` public class SysUserController extends BaseController {
private ISysUserService userService;
@Autowired
public void setUserService(ISysUserService userService) {
this.userService = userService;
}
} ```
需要注意的是,在使用Setter注入時需要加@Autowired
或@Resource
註解,否則是無法注入成功的。
另外要注意一點,屬性注入和Setter注入的變數都無法使用final
關鍵字修飾。
@RequiredArgsConstructor
這裡可能會有人說不推薦使用Lombok,只要我們知其然且知其所以然,那他就是一個幫助我們快速開發的好工具。
在說完Spring的三種依賴注入後,我們來認識一下Lombok的@RequiredArgsConstructor 註解。
在Lombok中,生成構造方法的註解一共有三個,分別是@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsContructor,我們這裡只介紹@RequiredArgsConstructor。
``` @Controller @RequiredArgsConstructor public class SysUserController extends BaseController {
private final ISysUserService userService;
private ISysRoleService roleService;
//---------------------------- } ```
使用@RequiredArgsConstructor會為我們生成一個包含常量、使用final關鍵字修飾的變數
的私有構造方法
。
那我們就可以不使用屬性注入(@Autowired和@Resource)的方式,直接通過構造器的方式來完成注入,不僅能夠省略簡化許多程式碼,也解決了屬性注入可能存在的空指標問題。