Spring Boot IOC and DI
Day 2 - 控制反轉 (IOC) vs 依賴注入(DI)
控制反轉 Inversion of Control (IOC)
控制反轉是一種程式設計的方式。它的精神在於程式中所需要的輔助物件,並不是在自己的類別中建立,而是由外部控制的。建立好後,將其傳遞給主程式,這個動作稱為依賴注入,是控制反轉的實現方式。
- 將 Object 的控制權交給外部的 Spring 容器來管理
依賴注入 dependency injection (DI)
實現控制反轉的方式,Spring 的設計目標之一是為了解隅,利用依賴抽象而非依賴實例的方式,因此設計了依賴注入(DI)。
- @Component , @RestController @Service … 等註各類解加在 class 上,將 class 交給 Spring 管理,這些也就是在 Spring Boot 中所謂的 Bean (後面章節會有詳細介紹)
- @Autowired 將被管理的 Bean 注入
應用範例
- 舉例來說有個物件專門來處理寄送訊息叫做 Sender ,我們需要使用到這個物件就必須透過 new 方法來建立出來,假設今天原本的 Sender 有問題更改成別種 Sender ,就必須有建立這個物件的地方都需要修改一遍,這時候改成用 DI 的方式就會比較容易維護及更動。
沒有使用 DI 方式,使用 New 方法來建立物件並引用
1 | public class Notify{ |
@Autowired 注入單一實做物件
將 Sender 交給 Spring 容器管理,使用 @Autowired 注入去使用,等於是透過 Spring 去建立物件出來
1 |
|
@Autowired 注入介面內含多個已實做物件
如果我們可能有多種 Sender 需要去實踐,可以用 interface 來建立一個介面去分成不同方法實踐
1 |
|
1 |
|
1 |
|
可以將 @Component 選擇注入其中一種,Spring 容器會自動幫我們選擇我們有注入的那個,但如果兩種都注入,就會出現錯誤,所以要再選擇用 @Qualifier(”bean 名稱”) 註解來指定要入住哪個
- 注意注入容器的 bean 名稱開頭是小寫
1 |
|
總結:
利用 IOC 和 DI 可以有以下優點:
- 鬆耦合
class 之間的鬆耦合,降低各個 class 之間的關聯性。
像是假設我們本來得在 Notify 中去指定要使用的是哪家廠牌的 MailSender(可能是 google, yahoo…) 而這就會讓 Notify 和 MailSender 的耦合變大,但使用了 Spring IoC 之後,不需要了解這個 Sender 是哪種,只要確定有被正確注入某種可以使用的 MailSender。
- 統一生命週期管理
交由 Spring 容器來管理這些物件的生命週期,減少不必要的引用。
因為我們將 MailSender 這個 object 改成是交由 Spring 容器來管理,因此 Spring 就會負責物件的創建、初始化、以及銷毀,所以就不需要我們親自去處理這件事情。
- 方便測試程式
可以方便注入至所需要測試的程式中
所有的 object 都是由外部的 Spring 容器來做管理,因此我們就可以輕鬆在測試程式內在測試的過程中,將 Spring 容器中的 object 給替換掉,容易的使用像是 Mock 的技術。
Ref:
- 古古的後端筆記 - Bean 的創建和注入 - @Component、@Autowired
- 控制反轉
- Spring Beans in Depth
- Java 工程師必備!Spring Boot 零基礎入門 (hahow 課程)