在Spring中提供了三種依賴注入的方式,基于屬性注入、基于構造器注入、基于setter注入。但是在Lombok中提供了一種新的注入方式@RequiredArgsConstructor 下面我們就來詳細介紹一下。
依賴注入
屬性注入
public class SysUserController extends BaseController {
@Autowired
private ISysUserService userService;
@Resource
private ISysRoleService roleService;
}
基于@Autowired預設是按照類型進行注入,如果沒有找到對應的類型則按照名稱注入。而@Resource則是先按照名稱進行注入,找不到對應的名稱的Bean的時候才會安裝類型進行注入。
而在Spring中還提供了一個@Qualifier 的注解與Autowired進行配合,用來指定名稱,進行裝配。
但是我們會發現如果在IDEA中在變量上直接使用了@Autowired 的注解會有一個Field injection is not recommended 的警告。原因就是官方會建議使用構造器進行注入,說明這種方式是存在弊端的。例如注入的對象不能用final修飾,無法發現空指針異常等等。
基于構造器注入
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;
}
}
構造器注入的方式是通過容器觸發類的構造器函數來實作,通過強制指定某個依賴的方式來注入這個類的行為。這樣可以防止發生空指針的異常。
而Spring官方推薦使用構造器注入不僅是為了防止空指針,而且還可以進行如上代碼中所示的操作可以通過final關鍵字進行修飾。但是這都不是重點,重點是這種方式可以有效的避免循環依賴,如果這個時候,出現了循環依賴,那麼在Spring項目啟動的時候會出現報錯。
有人會問,循環依賴不是已經被前置處理器、後置處理器解決了麼?為什麼這裡說可以避免循環依賴呢?
這是因為構造器注入是通過構造方法來生成對象,其必須要先擷取屬性,才能生成調用構造方法進行執行個體化,這種情況的循環依賴是無法解決的。
構造器方式可以通過如下的幾種方式來解決循環依賴問題
- 代碼重構
- @Lasy注解
- 改用屬性注入
Setter注入
public class SysUserController extends BaseController {
private ISysUserService userService;
@Autowired
public void setUserService(ISysUserService userService) {
this.userService = userService;
}
}
這種方式需要注意的是,在進行使用的時候需要添加@Autowired或者是@Resource的注解。否則是無法完成注入的。
另外需要注意的是通過setter和屬性的方式都是無法添加final關鍵字的。
@RequiredArgsConstructor
使用過Lombok的人一定知道這注解,但是也會有一部分人推薦不使用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關鍵字修飾的變量并且提供了對應的私有構造方法。
也就是說使用了@RequiredArgsConstructor注解之後,我們可以将上面三種注入方式所帶來的所有的優勢都進行了整合,這樣不但可以簡化很多的代碼,而且可以解決由于屬性注入所帶來的空指針的問題。