Spring框架中IoC的解讀

Spring框架是現在非常流行的框架之一,其兩大核心技術IoC(依賴注入/控制反轉)和AOP(面向切面編程),使得應用程序的組件更加快捷簡易。本文用實例先對IoC的做詳細介紹,希望對初學者有一定的幫助,本人能力有限,對於文章中的錯誤歡迎各位同道中人指正。
IoC使用兩大關鍵技術(JDOM、反射機制)和一個設計模式(工廠模式)來實現將組建對象的控制權從代碼本身轉移到外部容器,以降低代碼之間的耦合度。下面用代碼實例的形式來說明IoC原理。
1.dao層(一個接口)

package cn.dao;

public interface DaoInte{
    public void daoMethod();
}

2.dao實現層(兩個類)

package cn.dao.impl;
import cn.dao.DaoInter;

public class DaoClass1 implements DaoInter{
    @Override
    public void daoMethod() {
        System.out.println("假設這是這個類用來查詢數據庫的student表");
    }
}
package cn.dao.impl;
import cn.dao.DaoInter;

public class DaoClass2 implements DaoInter{
    @Override
    public void daoMethod() {
        System.out.println("假設這是這個類用來查詢數據庫的student表,此表經過大量的更新,包括表結構和數據");
    }
}

3.service層(一個接口)

package cn.service;

public interface ServiceInte {
    public void method1();
}

4.service實現層(一個類)

package cn.service.impl;
import cn.dao.DaoInte;
import cn.service.ServiceInte;

public class ServiceClass implements ServiceInte{
    private DaoInte dao;    //兩種方法調用dao層的daoMethod
    //---------不使用IoC-----------
    public void method1(){
        dao=new DaoClass1;   //創建dao實現層DaoClass1對象,當需求更改後要創建DaoClass2對象,這是就需要更改這裏的代碼
        dao.daoMethod();   //調用方法
    }   

    //---------使用IoC------------
    private DaoInte getDao() {
        return dao;
    }
    public void setDao(DaoInte dao) {
        this.dao = dao;
    }
    public void method1(){
        dao.daoMethod();
    }
}

5.Spring配置文件(使用IoC時)

<beans>
    <bean id="daoBean" class="cn.dao.impl.DaoClass1"></bean>      
<!-- class值爲類相對於配置文件的路徑,當需要更改dao實現類時,只需要更改這裏即可,即將class值改爲DaoClass2,而不需要更改代碼 -->
    <bean id="testService" class="cn.service.impl.ServiceClass">
        <property name="dao">   
        <!-- 給service實現層中的dao屬性賦值 ,實際上是在調用裏面的set方法,此處使用到*反射機制*-->
            <ref bean="daoBean"/>
        </property>
    </bean>
</beans>

可以看到,不使用Spring IoC時,調用service層,必須先new對象,將service層的接口指向具體的ServiceClass對象,才能調用其中的方法,即:

ServiceInte svi=new ServiceClass();
svi.method1();

這又將產生調用類與service層的耦合,當更改service層具體實現類時,就需要更改這裏的代碼。而在ServiceClass對象中需要調用dao層,此時也需要先new對象,將dao層接口指向具體的DaoClass1對象或者DaoClass2對象,這樣也產生了耦合關係,代碼見如上第4條不使用IoC。
總結就是,測試類管理service層的類的調用,service層管理dao層的類的調用,當更改dao層或service層的實現類,就需要更改代碼來實現,當更改的需求越來越多時,將會使代碼混亂。此時就需要解耦合,消除他們的依賴關係,可以建立一個bean工廠,在這個工廠中生成bean實例,並將這個實例推送給具體的調用類,那麼我在這個工廠中生成什麼樣的bean,要調用的類就使用什麼樣的bean,更改時只需要更改這個工廠要生成的bean的具體實現就可以了,spring利用配置文件來完成這個工廠的創建,這就是工廠模式,代碼如上第四條使用IoC和第五條配置文件的創建。到目前只是解決了service層與dao層的耦合關係,並沒有解決調用service層時產生的耦合關係,實際上我們在Spring配置文件中第二個bean已經產生了具體的ServiceClass對象,其id爲設置的”testService”,所以調用使就不再需要如上new對象,而是可以使用這裏的ServiceClass對象,使用方法如下:

//加載配置文件(相對路徑)  
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml"); 
//加載配置文件(絕對文件)
//new FileSystemXmlApplicationContext("..");  
ServiceClass sc=(ServiceClass)ctx.getBean("testService");
sc.method1();

這樣就解決了調用service層時的耦合問題,當service層變更時只需要更改配置文件裏的路徑指向,而不需要更改代碼。下面用一張圖簡單解釋這種關係:
不使用IoC與使用IoC的區別
因此IoC被翻譯爲依賴注入或控制反轉。通俗的說,IoC使得原本程序中需要什麼樣的對象就new什麼樣的對象變成配置文件的bean工廠給什麼樣的對象就使用什麼樣的對象,是一個由主動變被動的過程。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章