1、什麼是依賴注入
依賴注入(Dependency Injection,簡稱DI),是IOC的一種別稱,用來減少物件間的依賴關係。
提起依賴注入,就少不了IOC。
IOC(Inversion of Control,控制反轉)是一種設計思想,它將原本在程式中手動建立物件的控制權,交由Spring框架來管理。
IOC和DI,是同一個概念的不同角度描述。(IOC是一種思想,DI則是該思想的一種具體的技術實現方案。)
也可以這麼理解:
IOC是目的(目的是建立物件),DI是手段(透過什麼手段獲取外部物件)。
2、依賴注入的常見實現方式
- 建構函式注入
- setter方法注入
- 屬性注入
2.1 建構函式注入
將各個必需的依賴全部放在帶有註解構造方法的引數中,並在構造方法中完成對應變數的初始化,這種方式,就是基於構造方法的注入。
@RestController
public class UserController {
// 構造方法注入
private UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@RequestMapping("/add")
public UserInfo add(String username, String password) {
return userService.add(username, password);
}
}
該方式的優點:
- 可注入不可變物件
- 注入物件不會被修改
- 注入物件會被完全初始化
- 通用性更好
該方式的缺點:
- 當需要依賴的物件過多,構造方法會臃腫
2.2 setter方法注入
在JavaBean中,通常會透過setXXX()和getXXX()方法來訪問對應屬性。
這些setXXX()方法統稱為setter方法,getXXX()方法統稱為getter方法。
透過setter方法,可以更改相應的物件屬性,透過getter方法,可以獲得相應屬性的狀態。
所以,當前物件只要為其依賴物件所對應的屬性新增setter方法,就可以透過setter方法將相應的依賴物件設定到被注入物件中。
@Service
public class UserService {
private SmsService smsService;
@Autowired //透過setter方法實現注入
public void setWolf3Bean(SmsService smsService) {
this.smsService = smsService;
}
}
該方式的優點:
- 完全符合單一職責的設計原則,因為每一個 Setter 只針對一個物件
該方式的缺點:
- 不能注入不可變物件(final 修飾的物件)
- 注入的物件可被修改
2.3 屬性注入
屬性注入,就是在bean的變數上使用註解進行依賴注入。
屬性注入是我們最熟悉的,也是日常開發中使用最多的一種注入方式,它的實現程式碼如下:
@RestController
public class UserController {
// 屬性物件
@Autowired
private UserService userService;
@RequestMapping("/add")
public UserInfo add(String username, String password) {
return userService.add(username, password);
}
}
該方式的優點:
- 使用簡單
該方式的缺點:
- 不能注入不可變物件(final 修飾的物件)
- 注入的物件可被修改
- 只能適應於 IoC 容器
3、總結
在實際開發中,根據不同的場景,選擇不同的注入方式。
簡單來說,就是
- 強制依賴就用構造器方式
- 可選、可變的依賴就用setter注入
但,日常開發應該還是屬性注入較多~