我對控制反轉以及依賴注入的認識
IoC誕生的歷史
在沒有IoC時,關聯不同模組是通過類例項實現的,程式碼可能是這樣子的:
// 程式碼清單1
public interface YourService {
void func1();
void func2();
}
// 程式碼清單2
public class MyServiceImpl {
private YourServiceImpl yourServiceImpl;
public MyServiceImpl() {
this.yourServiceImpl = new YourServiceImpl();
}
public void process() {
// do something
this.yourServiceImpl.func1(...);
// do something
this.yourServiceImpl.func2(...);
}
}
// 程式碼清單3
public class MyServiceImpl {
private YourService yourService;
public MyServiceImpl(YourService yourService) {
this.yourService = yourService;
}
public void process() {
// do something
this.yourService.func1(...);
// do something
this.yourService.func2(...);
}
}
當YourServiceImpl的介面不變時,只需要根據業務需要更換不同的YourService實現類即可。一旦更換實現類時(如將yourServiceImpl更換為NewServiceImpl),MyServiceImpl中所有引用YourService的程式碼都要替換為NewServiceImpl,這嚴重違背了物件導向設計中DIP(Dependence Inversion Principle)原則。
* 上層業務應該依賴抽象,抽象定義了"要做什麼",而不應依賴實現細節"怎麼做"。
* 模組間通過介面建立依賴關係
* 實現類依賴介面或抽象類
IOC實現的原理
IoC: Inversion of Control(依賴反轉), 是針對之前模組間通過實現類建立關聯而言,反轉指”模組實現依賴實現類”->”模組實現依賴(實現類的)介面”。
執行IoC原則後,模組內原本生成例項的語句被替換成介面呼叫(程式碼清單3)。我們知道JVM是在執行時才申請記憶體並生成類例項物件的,執行時系統怎麼知曉具體介面對應的實現是什麼呢?
這時候就輪到反射和DI登場了。DI(Dependency injection)依賴注入,在執行時根據spring的xml配置檔案(有實現類的全路徑名稱)選擇適當的時機構造依賴物件例項並注入到依賴實現類介面的模組中。而如何完成依賴例項物件的構造以及初始化是Spring DI的核心。
// 程式碼清單4
<bean id="userDAO" class="dao.impl.UserDAOImpl">
<property name="sellerDAO" ref="sellerDAO" />
</bean>
<bean id="sellerDAO" class="dao.impl.SellerDAOImpl" />
程式碼清單4中演示了spring的bean配置程式碼。Spring解析bean的xml檔案,拿到bean的類全路徑名稱後呼叫Class.forName(String className)方法從對應的類載入器中獲取類資訊,並呼叫Class.newInstance()方法生成類例項。
此時類例項並未完成初始化,還需要注入類例項的依賴項。Spring解析bean下的property條目,以property name為優先查詢例項類的set方法並匹配入參,如果有則調set方法注入property。此時給模組返回完整的依賴物件。
注入方法
set方法注入
該方式要求被注入的屬性在實現類裡有set方法。set注入支援簡單型別和引用型別。
建構函式注入
// 程式碼清單5
/**
* Created by fujianbo on 2018/6/17.
*
* @author fujianbo
* @date 2018/06/17
*/
public class UserDAOImpl implements UserDAO {
private SellerDAO sellerDAO;
public void setSellerDAO(SellerDAO sellerDAO) {
this.sellerDAO = sellerDAO;
}
public UserDAOImpl() {
}
public UserDAOImpl(SellerDAO sellerDAO) {
this.sellerDAO = sellerDAO;
}
}
// 程式碼清單6
<bean id="sellerDAO" class="dao.impl.SellerDAOImpl" />
<bean id="userDAO" class="dao.impl.UserDAOImpl">
<constructor-arg ref="sellerDAO"/>
</bean>
當有多個constructor-arg時,Spring根據傳入的依賴引數找到對應的建構函式而並不關心書寫順序。但如果建構函式只是入參順序不同,定義constructor-arg時需要加index引數,否則Spring建立類例項失敗。
// 程式碼清單7
public class User {
private String userName;
private Integer age;
public User(int age, String userName) {
this.age = age;
this.userName = userName;
}
public User(String userName, int age) {
this.userName = userName;
this.age = age;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public void setAge(Integer age) {
this.age = age;
}
}
...
// yourConfig.xml
<bean id="user" class="..." >
<constructor-arg index="0" value="Jack"/>
<constructor-arg index="1" value="26"/>
</bean>
IoC & DI
以下個人對於這兩個兄弟的理解,如有謬誤還請指正!
IoC
1、IoC(控制反轉)是模組間拜託對類例項依賴的橋樑,它統一管理了類例項物件的建立、初始化、注入以及銷燬過程。
2、模組間依賴實現類的介面,從呼叫者角度來看,多數情況無需關注細節以及感知實現細節的變化,只需關注介面入參和返回值,將OOP上升到面向介面、面向切面程式設計的層次,是工廠模式的昇華(參考引用2)。每個模組相當於一個垂直業務,IoC抽象了模組內部建立類例項的程式碼,依託反射和DI,給出了類例項型別識別解析、初始化、物件管理(spring容器)的解決方案。
3、當模組間不再顯示建立類例項總得有人接下這項”苦差事”吧,這人就是Spring。Spring通過bean配置檔案或者@Autowired, @Component, @Resource(J2EE提供), @Service, @Repository等註解,結合java反射原理生成類例項物件並給模組間的介面賦值。
DI
Spring提供的傳遞模組間依賴的介面的例項的方法,是IoC解決方案的一部分。
引用
相關文章
- 依賴注入和控制反轉依賴注入
- 對控制反轉和依賴注入的突然頓悟依賴注入
- 前端理解依賴注入(控制反轉)前端依賴注入
- Spring 控制反轉和依賴注入Spring依賴注入
- .NET IoC模式依賴反轉(DIP)、控制反轉(Ioc)、依賴注入(DI)模式依賴注入
- 淺析依賴倒轉、控制反轉、IoC 容器、依賴注入。依賴注入
- Java:控制反轉(IoC)與依賴注入(DI)Java依賴注入
- PHP 控制反轉(IoC) 和 依賴注入(DI)PHP依賴注入
- PHP 控制反轉(IOC)和依賴注入(DI)PHP依賴注入
- 面試官:你是如何理解Java中依賴倒置和依賴注入以及控制反轉的?面試Java依賴注入
- 控制反轉,依賴注入,依賴倒置傻傻分不清楚?依賴注入
- 8.(轉)控制反轉(IoC)與依賴注入(DI)依賴注入
- 深入理解IoC(控制反轉)、DI(依賴注入)依賴注入
- 依賴倒置、依賴注入和控制反轉傻傻分不清楚?依賴注入
- php實現依賴注入(DI)和控制反轉(IOC)PHP依賴注入
- Spring理論基礎-控制反轉和依賴注入Spring依賴注入
- 反射,註解,動態代理,依賴注入控制反轉反射依賴注入
- 深入理解控制反轉(IoC)和依賴注入(DI)依賴注入
- 理解Spring中依賴注入(DI)與控制反轉(IoC)Spring依賴注入
- CommunityToolkit.Mvvm8.1 IOC依賴注入控制反轉(5)UnityMVVM依賴注入
- 學習記錄-Laravel 核心 依賴注入 控制反轉 反射Laravel依賴注入反射
- 什麼是控制反轉(IOC)?什麼是依賴注入?依賴注入
- PHP DIY 系列------框架篇:8. 依賴注入和控制反轉PHP框架依賴注入
- DIY 實現 ThinkPHP 核心框架(八)控制反轉和依賴注入PHP框架依賴注入
- 控制反轉(IOC)與依賴注入(DI)模式解析及實踐依賴注入模式
- 深入理解spring容器中的控制反轉(IOC)和依賴注入(DI)Spring依賴注入
- OOD、DIP、IOC、DI、依賴注入容器(即 控制反轉容器,IOC Container)依賴注入AI
- 我看依賴注入依賴注入
- .NET Core ASP.NET Core Basic 1-2 控制反轉與依賴注入ASP.NET依賴注入
- 寫一個簡單的IoC容器案例,理解什麼是依賴注入和控制反轉依賴注入
- Spring系列第二講 控制反轉(IoC)與依賴注入(DI),晦澀難懂麼?Spring依賴注入
- 深入探討控制反轉(IOC)與依賴注入(DI)模式原理與應用實踐依賴注入模式
- 我對CDN以及CDN加速的認識
- 依賴注入?依賴注入是如何實現解耦的?依賴注入解耦
- 你確定懂?徹底搞懂 控制反轉(IoC Inversion of Control )與依賴注入(DI Dependency Inversion Principle )依賴注入
- 比nestjs更優雅的ts控制反轉策略-依賴查詢JS
- spring 的依賴注入Spring依賴注入
- Spring之初識Ioc(控制反轉)以及引入SpringSpring