posts - 51, comments - 17, trackbacks - 0, articles - 9
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          Spring中IoC的入門實(shí)例

          Posted on 2007-03-21 21:15 chenweicai 閱讀(157) 評論(0)  編輯  收藏
          Spring的模塊化是很強(qiáng)的,各個功能模塊都是獨(dú)立的,我們可以選擇的使用。這一章先從Spring的IoC開始。所謂IoC就是一個用XML來定義生成對象的模式,我們看看如果來使用的。
          1、數(shù)據(jù)模型。
          1、如下圖所示有三個類,Human(人類)是接口,Chinese(中國人)是一個子類,American(美國人)是另外一個子類。


          源代碼如下:
          package cn.com.chengang.spring;
          public interface Human {
          ?????? void eat();
          ?????? void walk();
          }
          ?
          package cn.com.chengang.spring;
          public class Chinese implements Human {
          ??? /* (非 Javadoc)
          ???? * @see cn.com.chengang.spring.Human#eat()
          ???? */
          ??? public void eat() {
          ??????? System.out.println("中國人對吃很有一套");
          ??? }
          ?
          ??? /* (非 Javadoc)
          ???? * @see cn.com.chengang.spring.Human#walk()
          ???? */
          ??? public void walk() {
          ??????? System.out.println("中國人行如飛");
          ??? }
          }
          ?
          package cn.com.chengang.spring;
          public class American implements Human {
          ??? /* (非 Javadoc)
          ???? * @see cn.com.chengang.spring.Human#eat()
          ???? */
          ??? public void eat() {
          ??????? System.out.println("美國人主要以面包為主");
          ??? }
          ?
          ??? /* (非 Javadoc)
          ???? * @see cn.com.chengang.spring.Human#walk()
          ???? */
          ??? public void walk() {
          ??????? System.out.println("美國人以車代步,有四肢退化的趨勢");
          ??? }
          }
          ?
          2、對以上對象采用工廠模式的用法如下
          創(chuàng)建一個工廠類Factory,如下。這個工廠類里定義了兩個字符串常量,所標(biāo)識不同的人種。getHuman方法根據(jù)傳入?yún)?shù)的字串,來判斷要生成什么樣的人種。
          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("參數(shù)(人種)錯誤");
          ??? }
          }
          ?
          下面是一個測試的程序,使用工廠方法來得到了不同的“人種對象”,并執(zhí)行相應(yīng)的方法。
          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();
          ??? }
          }
          ?
          控制臺的打印結(jié)果如下:
          ?
          3、采用Spring的IoC的用法如下:
          1、在項目根目錄下創(chuàng)建一個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目錄下的。
          ?
          2、修改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就相當(dāng)于原來的Factory工廠,原來的Factory就可以刪除掉了。然后又把Factory里的兩個常量移到了ClientTest類里,整個程序結(jié)構(gòu)基本一樣。
          再回頭看原來的bean.xml文件的這一句
          <bean id="Chinese" class="cn.com.chengang.spring.Chinese"/>
          id就是ctx.getBean的參數(shù)值,一個字符串。class就是一個類(包名+類名)。然后在ClientTest類里獲得Chinese對象就是這么一句
          human = (Human) ctx.getBean(CHINESE);
          因?yàn)間etBean方法返回的是Object類型,所以前面要加一個類型轉(zhuǎn)換。
          ?
          4、總結(jié)
          (1)也許有人說,IoC和工廠模式不是一樣的作用嗎,用IoC好象還麻煩一點(diǎn)。
          ?????? 舉個例子,如果用戶需求發(fā)生變化,要把Chinese類修改一下。那么前一種工廠模式,就要更改Factory類的方法,并且重新編譯布署。而IoC只需 要將class屬性改變一下,并且由于IoC利用了Java反射機(jī)制,這些對象是動態(tài)生成的,這時我們就可以熱插撥Chinese對象(不必把原程序停止 下來重新編譯布署)
          ?
          ?????? (2)也許有人說,即然IoC這么好,那么我把系統(tǒng)所有對象都用IoC方式來生成。
          ?????? 注意,IoC的靈活性是有代價的:設(shè)置步驟麻煩、生成對象的方式不直觀、反射比正常生成對象在效率上慢一點(diǎn)。因此使用IoC要看有沒有必要,我認(rèn)為比較通用的判斷方式是:用到工廠模式的地方都可以考慮用IoC模式。
          ?
          ?????? (3)在上面的IoC的方式里,還有一些可以變化的地方。比如,bean.xml不一定要放在項目錄下,也可以放在其他地方,比如cn.com.chengang.spring包里。不過在使用時也要變化一下,如下所示:
          new FileSystemXmlApplicationContext("src/cn/com/chengang/spring/bean.xml");
          另外,bean.xml也可以改成其他名字。這樣我們在系統(tǒng)中就可以分門別類的設(shè)置不同的bean.xml。
          ?
          (4)關(guān)于IoC的低侵入性。
          什 么是低侵入性?如果你用過Struts或EJB就會發(fā)現(xiàn),要繼承一些接口或類,才能利用它們的框架開發(fā)。這樣,系統(tǒng)就被綁定在Struts、EJB上了, 對系統(tǒng)的可移植性產(chǎn)生不利的影響。如果代碼中很少涉及某一個框架的代碼,那么這個框架就可以稱做是一個低侵入性的框架。
          Spring的侵入性很低,Humen.java、Chinese.java等幾個類都不必繼承什么接口或類。但在ClientTest里還是有一些Spring的影子:FileSystemXmlApplicationContext類和ctx.getBean方式等。
          現(xiàn)在,低侵入性似乎也成了判定一個框架的實(shí)現(xiàn)技術(shù)好壞的標(biāo)準(zhǔn)之一。
          ?
          (5)關(guān)于bean.xml的用法
          bean.xml 的用法還有很多,其中內(nèi)容是相當(dāng)豐富的。假設(shè)Chinese類里有一個humenName屬性(姓名),那么原的bean.xml修改如下。此后生成 Chinese對象時,“陳剛”這個值將自動設(shè)置到Chinese類的humenName屬性中。而且由于singleton為true這時生成 Chinese對象將采用單例模式,系統(tǒng)僅存在一個Chinese對象實(shí)例。
          <?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>
          ?
          關(guān)于bean.xml的其它用法,不再詳細(xì)介紹了,大家自己拿Spring的文檔一看就明白了。

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 赫章县| 资源县| 正定县| 喜德县| 长沙县| 金湖县| 鄂托克前旗| 页游| 宜兴市| 梁河县| 灵石县| 焦作市| 泾阳县| 白玉县| 锡林郭勒盟| 来宾市| 邵东县| 关岭| 罗平县| 长宁县| 西平县| 云霄县| 北辰区| 犍为县| 福州市| 五峰| 泌阳县| 金寨县| 新巴尔虎右旗| 来凤县| 洪洞县| 潜江市| 沁源县| 虞城县| 陵川县| 华安县| 井研县| 嘉荫县| 左贡县| 兴和县| 舒城县|