Spring中IoC的入門實例

Spring的模塊化是很強的,各個功能模塊都是獨立的,我們可以選擇的使用。這一章先從Spring的IoC開始。所謂IoC就是一個用XML來定義生成對象的模式,我們看看如果來使用的。

1、如下圖所示有三個類,Human(人類)是接口,Chinese(中國人)是一個子類,American(美國人)是另外一個子類。

   20071203101224550.jpg 

源代碼如下:

package cn.com.chengang.spring;

public interface Human {void eat();void walk();}

package cn.com.chengang.spring;

public class Chinese implements Human {

public void eat() {System.out.println("中國人對吃很有一套");}

 public void walk() {System.out.println("中國人行如飛");}

}

package cn.com.chengang.spring;

public class American implements Human {

public void eat() {System.out.println("美國人主要以麪包爲主");}

public void walk() {System.out.println("美國人以車代步,有四肢退化的趨勢");}

}

2、對以上對象採用工廠模式的用法如下  

創建一個工廠類Factory,如下。這個工廠類裏定義了兩個字符串常量,所標識不同的人種。getHuman方法根據傳入參數的字串,來判斷要生成什麼樣的人種。

package cn.com.chengang.spring;

 public class Factory {

public final static String CHINESE = "Chinese";

public final static String AMERICAN = "American";

public Human getHuman(String ethnic) {

 if (ethnic.equals(CHINESE))return new Chinese();

else if (ethnic.equals(AMERICAN))return new American();

else  throw new IllegalArgumentException("參數(人種)錯誤");}

 }

 下面是一個測試的程序,使用工廠方法來得到了不同的“人種對象”,並執行相應的方法。

package cn.com.chengang.spring;

public class ClientTest {public static void main(String[] args) {

Human human = null;

human = new Factory().getHuman(Factory.CHINESE);

human.eat();human.walk();

human = new Factory().getHuman(Factory.AMERICAN);

human.eat();human.walk();}

}   

控制檯的打印結果如下:

 20071203101225373.jpg           

3、採用Spring的IoC的用法如下: 

在項目根目錄下創建一個bean.xml文件

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<bean id="Chinese" class="cn.com.chengang.spring.Chinese"/>

<bean id="American" class="cn.com.chengang.spring.American"/>

</beans>  

bean.xml的位置如下圖,注意不要看花眼把它看成是lib目錄下的了,它是在myspring目錄下的。

 20071203101226861.jpg

修改ClientTest程序如下:

package cn.com.chengang.spring;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.FileSystemXmlApplicationContext;

public class ClientTest {

public final static String CHINESE = "Chinese";

public final static String AMERICAN = "American";

public static void main(String[] args) {

// Human human = null;

// human = new Factory().getHuman(Factory.CHINESE);

// human.eat();

// human.walk();

// human = new Factory().getHuman(Factory.AMERICAN);

// human.eat();

// human.walk();

ApplicationContext ctx = new FileSystemXmlApplicationContext("bean.xml");

Human human = null;

human = (Human) ctx.getBean(CHINESE);

human.eat();

human.walk();

human = (Human) ctx.getBean(AMERICAN);

human.eat();human.walk();}

}

從這個程序可以看到,ctx就相當於原來的Factory工廠,原來的Factory就可以刪除掉了。然後又把Factory裏的兩個常量移到了ClientTest類裏,整個程序結構基本一樣。  

再回頭看原來的bean.xml文件的這一句:  

<bean id="Chinese" class="cn.com.chengang.spring.Chinese"/>  

id就是ctx.getBean的參數值,一個字符串。class就是一個類(包名+類名)。然後在ClientTest類裏獲得Chinese對象就是這麼一句  

human = (Human) ctx.getBean(CHINESE);  

因爲getBean方法返回的是Object類型,所以前面要加一個類型轉換。  

總結  

(1)也許有人說,IoC和工廠模式不是一樣的作用嗎,用IoC好象還麻煩一點。  

舉個例子,如果用戶需求發生變化,要把Chinese類修改一下。那麼前一種工廠模式,就要更改Factory類的方法,並且重新編譯佈署。而IoC只需要將class屬性改變一下,並且由於IoC利用了Java反射機制,這些對象是動態生成的,這時我們就可以熱插撥Chinese對象(不必把原程序停止下來重新編譯佈署)  

(2)也許有人說,即然IoC這麼好,那麼我把系統所有對象都用IoC方式來生成。  

注意,IoC的靈活性是有代價的:設置步驟麻煩、生成對象的方式不直觀、反射比正常生成對象在效率上慢一點。因此使用IoC要看有沒有必要,我認爲比較通用的判斷方式是:用到工廠模式的地方都可以考慮用IoC模式。  

(3)在上面的IoC的方式裏,還有一些可以變化的地方。比如,bean.xml不一定要放在項目錄下,也可以放在其他地方,比如cn.com.chengang.spring包裏。不過在使用時也要變化一下,如下所示:  

new FileSystemXmlApplicationContext("src/cn/com/chengang/spring/bean.xml");  

另外,bean.xml也可以改成其他名字。這樣我們在系統中就可以分門別類的設置不同的bean.xml.   

(4)關於IoC的低侵入性。  

什麼是低侵入性?如果你用過Struts或EJB就會發現,要繼承一些接口或類,才能利用它們的框架開發。這樣,系統就被綁定在Struts、EJB上了,對系統的可移植性產生不利的影響。如果代碼中很少涉及某一個框架的代碼,那麼這個框架就可以稱做是一個低侵入性的框架。  

Spring的侵入性很低,Humen.java、Chinese.java等幾個類都不必繼承什麼接口或類。但在ClientTest裏還是有一些Spring的影子:FileSystemXmlApplicationContext類和ctx.getBean方式等。  

(5)關於bean.xml的用法  

bean.xml的用法還有很多,其中內容是相當豐富的。假設Chinese類裏有一個humenName屬性(姓名),那麼原的bean.xml修改如下。此後生成Chinese對象時,“陳剛”這個值將自動設置到Chinese類的humenName屬性中。而且由於singleton爲true這時生成Chinese對象將採用單例模式,系統僅存在一個Chinese對象實例。

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<bean id="Chinese" class="cn.com.chengang.spring.Chinese" singleton="true">

<property name="humenName">

<value>陳剛</value>

</property>

</bean>

<bean id="American" class="cn.com.chengang.spring.American"/>

</beans>

發佈了14 篇原創文章 · 獲贊 1 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章