Spring架構IOC反轉控制的了解
- 寫在前面
-
- 詳細說說
- 從執行個體中分析
寫在前面
終于到了Spring架構的學習,看了一堆資料,幾乎每種資料都會先去強調IOC的重要性。那麼,什麼是IOC???名詞解釋一波:inversion of control 反轉控制。那麼,深入的了解一下:反轉什麼?控制什麼? ------反轉建立對象的控制權:建立對象的控制權一直在我們手裡,通過new方法即可。但是spring裡面的ioc是将建立對象的控制權給了外部元件。那麼,問題又來了,為啥這麼做呢?
在我們新手的程式設計世界裡,接口需要實作類來實作,那麼接口類和實作類之間會有非常強的耦合,這種強耦合不适合程式的拓展,我們希望得到是*“高内聚,低耦合”*的程式設計模式。
那麼是否可以将接口和實作類之間的強耦合關系進行解耦呢?當然!
詳細說說
我們來整理一下最簡單的思路:
1.将接口建立,丢在一邊;
2.将實作類建立,同樣丢在一邊,同樣不管它死活,千萬不要用這個實作類去實作剛剛建立的接口;
3.建立工廠類,工廠類就是聯系接口和實作類的工具。“工廠”會告訴程式哪個接口該用哪個實作類來實作:通過解析提前寫好的xml檔案即可。
那麼整合上面的思路,我們就會得到一個最最簡單的Sping IOC的底層實作。下面我們舉一個最簡單的web project來加深了解。如下圖
所示,這是一個非常簡單的web項目
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL0IzM4QjNwIjM3ITOwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
從執行個體中分析
下面我們結合上面的IOC底層實作思路,逐個分析。
首先是UserService接口類,無視我随便取的方法名就好 - -:
public interface UserService {
public void ztxm();
}
接着我們來整這個接口的實作類UserServiceImpl:
public class UserServiceImpl implements UserService {
@Override
public void ztxm() {
// TODO Auto-generated method stub
System.out.println("UserServiceImpl被執行了!!!");
}
}
再寫一個實作類:
public class UserServiceImpl1 implements UserService {
@Override
public void ztxm() {
// TODO Auto-generated method stub
System.out.println("UserServiceImpl1被執行了!!!");
}
}
那麼到現在位置,接口和其對應的實作類都寫完了,按照以前的強耦合關系,我們隻需在測試單元中new對象即可:
public void demo1(){
UserServiceImpl userservice = new UserServiceImp();
userservice.save();
}
但是此時建立的接口和實作類之間的關系是強耦合關系,我們希望得到的是解耦合,是以就引出了配置檔案,我這裡建立的是xml:
<?xml version="1.0" encoding="UTF-8"?>
<!-- 引入具體的限制 -->
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" x
si:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--spring的入門配置============ -->
<bean id="UserService" class="spring_day01_demo1.UserServiceImpl1">
</bean>
</beans>
bean關聯的是接口,其相應的實作類的位址在後面的class裡面,工廠類會去讀取這個xml檔案,利用反射實作對接口的執行個體化,并調用方法。
最關鍵的”工廠“如下:
public void demo2(){
//建立spring工廠
ClassPathXmlApplicationContext applicationContext = new
ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService)applicationContext.getBean("UserService");
userService.ztxm();
}
建立完工廠類之後,其會去讀取xml檔案,并根據需要執行個體化的接口名,實際傳回該接口執行個體化後的對象,并調用方法。具體選擇哪一個實作類實作接口,代碼層面是看不到的,這些資訊封裝在xml配置檔案中:
如,現在配置檔案映射的實作類是UserServiceImpl,那我們運作測試單元,運作結果如下:
明顯,調用的是UserServiceImpl的實作類實作接口,那我們修改配置檔案:
現在調用的實作類變成了UserServiceImpl1,再次運作,結果如下:
結果符合自己的預期~~驗證project配置正确!也再次證明了spring的IOC底層實作是松耦合的。