天天看點

Spring架構IOC反轉控制的了解寫在前面

Spring架構IOC反轉控制的了解

  • 寫在前面
    • 詳細說說
    • 從執行個體中分析

寫在前面

終于到了Spring架構的學習,看了一堆資料,幾乎每種資料都會先去強調IOC的重要性。那麼,什麼是IOC???名詞解釋一波:inversion of control 反轉控制。那麼,深入的了解一下:反轉什麼?控制什麼? ------反轉建立對象的控制權:建立對象的控制權一直在我們手裡,通過new方法即可。但是spring裡面的ioc是将建立對象的控制權給了外部元件。那麼,問題又來了,為啥這麼做呢?

在我們新手的程式設計世界裡,接口需要實作類來實作,那麼接口類和實作類之間會有非常強的耦合,這種強耦合不适合程式的拓展,我們希望得到是*“高内聚,低耦合”*的程式設計模式。

那麼是否可以将接口和實作類之間的強耦合關系進行解耦呢?當然!

詳細說說

我們來整理一下最簡單的思路:

1.将接口建立,丢在一邊;

2.将實作類建立,同樣丢在一邊,同樣不管它死活,千萬不要用這個實作類去實作剛剛建立的接口;

3.建立工廠類,工廠類就是聯系接口和實作類的工具。“工廠”會告訴程式哪個接口該用哪個實作類來實作:通過解析提前寫好的xml檔案即可。

那麼整合上面的思路,我們就會得到一個最最簡單的Sping IOC的底層實作。下面我們舉一個最簡單的web project來加深了解。如下圖

所示,這是一個非常簡單的web項目

Spring架構IOC反轉控制的了解寫在前面

從執行個體中分析

下面我們結合上面的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,那我們運作測試單元,運作結果如下:

Spring架構IOC反轉控制的了解寫在前面

明顯,調用的是UserServiceImpl的實作類實作接口,那我們修改配置檔案:

現在調用的實作類變成了UserServiceImpl1,再次運作,結果如下:

Spring架構IOC反轉控制的了解寫在前面

結果符合自己的預期~~驗證project配置正确!也再次證明了spring的IOC底層實作是松耦合的。