Spring IoC 使用詳解

fmms 12年前發布 | 107K 次閱讀 Spring JEE框架

在Spring中,依賴注入(DI)模式實現了控制反轉(IoC)原理。讓我們通過一個例子來幫助理解依賴注入。我們先看到java版的例子,然后在此基礎上加上spring的功能。就例子而言,是相當地簡單。QuizMater接口暴露了popQuestion()方法。為了保持簡單性,QuizMaster將只生成一個問題。

 

/**
 * QuizMaster.java
 */
package com.vaannila;

public interface QuizMaster {

    public String popQuestion();
}

StrutsQuizMaster和SpringQuizMaster類實現了QuizMaster接口,它們各自生成struts和spring相關的問題。

 

/**
 * StrutsQuizMaster.java
 */
package com.vaannila;

public class StrutsQuizMaster implements QuizMaster {

    @Override
    public String popQuestion() {
        return "Are you new to Struts?";
    }

}

/**
 * SpringQuizMaster.java
 */
package com.vaannila;

public class SpringQuizMaster implements QuizMaster {

    @Override
    public String popQuestion() {
        return "Are you new to Spring?";
    }

}

有個QuizMasterService類向用戶顯示問題。QuizMasterService類關聯了QuizMaster接口。

 

/**
 * QuizMasterService.java
 */
package com.vaannila;

public class QuizMasterService {

    private QuizMaster quizMaster = new SpringQuizMaster();

    public void askQuestion(){
        System.out.println(quizMaster.popQuestion());
    }
}

最后創建QuizProgram類來管理測驗。

 

/**
 * QuizProgram.java
 */
package com.vaannila;

public class QuizProgram {

    public static void main(String[] args) {
        QuizMasterService quizMasterService = new QuizMasterService();
        quizMasterService.askQuestion();
    }

}

看上去相當的簡單,我們創建了QuizMasterService類的實例,并且調用了askQuestion()方法。當你執行program,期望的“Are you new to Spring?”將從控制臺打印出來。

再看看這個例子的類圖。綠色箭頭表示泛化,藍色箭頭表示關聯。

Spring IoC 使用詳解

 看的出來這種結構是緊密耦合在一起的。在QuizMasterService類中創建了QuizMaster的實例,如下所示。

 

private QuizMaster quizMaster = new SpringQuizMaster();

為了測驗精通struts的人,我們需要修改QuizMasterService成這樣:

 

private QuizMaster quizMaster = new StrutsQuizMaster();

因此耦合性是非常高的,這就是為什么要使用依賴注入來避免這種耦合。Spring框架提供了非常強大的容器來管理組件。容器就是基于控制反轉(IoC)理念并且實現了依賴注入。這些組件僅僅需要選擇一種接受資源的方式,容器會自動為組件推送資源。

下面我們替換為QuizMasterService類直接創建QuizMaster對象的方式,讓容器來承擔這項工作。替換了硬編碼,允許容器來注入需要的依賴項。

注入依賴使用setter或構造方法注入。下面看看怎樣使用setter來注入。

 

/**
 * QuizMasterService.java
 */
package com.vaannila;

public class QuizMasterService {

    private QuizMaster quizMaster;

    public void setQuizMaster(QuizMaster quizMaster) {
        this.quizMaster = quizMaster;
    }

    public void askQuestion(){
        System.out.println(quizMaster.popQuestion());
    }
}

QuizMaster的值使用setQuizMaster()方法設置。在QuizMasterService類中,QuizMaster對象沒有實例化,但仍然來訪問它。通常這樣做會拋出NullPointerException異常,但是容器已經實例化了這個對象,因此能很好的工作。

再作了這些改變之后,例子的類圖就變成這樣了。

Spring IoC 使用詳解

 圖中多了容器,它幫助注入依賴項。

在beans.xml文件中的beans配置:

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="springQuizMaster" class="com.vaannila.SpringQuizMaster"></bean>
    <bean id="strutsQuizMaster" class="com.vaannila.StrutsQuizMaster"></bean>
    <bean id="quizMasterService" class="com.vaannila.QuizMasterService">

        <property name="quizMaster">
            <ref local="springQuizMaster" />
        </property>
    </bean>
</beans>

定義每個bean使用bean標簽。bean標簽的id屬性是獲取這個bean的邏輯名,class屬性表示了真實的bean類。property標簽指向bean的屬性。使用setter注入一個bean需要使用ref標簽。

SpringQuizMaster的引用被注入到QuizMasterbean。當我們執行這個例子,控制臺打印出“Are you new to Spring?”。

為了使QuizMaster問一個struts相關的問題,僅僅需要改變ref標簽的指向。

 

    <bean id="quizMasterService" class="com.vaannila.QuizMasterService">
        <property name="quizMaster">

            <ref local="strutsQuizMaster" />
        </property>
    </bean>

依賴注入降低了組件之間的耦合。

要執行這個例子需要把如下的jar文件加大classpath。

antlr-runtime-3.0
commons-logging-1.0.4
org.springframework.asm-3.0.0.M3
org.springframework.beans-3.0.0.M3
org.springframework.context-3.0.0.M3
org.springframework.context.support-3.0.0.M3
org.springframework.core-3.0.0.M3
org.springframework.expression-3.0.0.M3

 本文由用戶 fmms 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!