<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 63  文章 - 0  trackbacks - 0
    <2009年4月>
    2930311234
    567891011
    12131415161718
    19202122232425
    262728293012
    3456789

    常用鏈接

    留言簿(2)

    隨筆分類

    隨筆檔案

    搜索

    •  

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

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

       數(shù)據(jù)模型

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

    源代碼如下:

    java 代碼
    1. package cn.com.chengang.spring;   
    2. public interface Human {   
    3. void eat();   
    4. void walk();   
    5. }   
    6.   
    7. package cn.com.chengang.spring;   
    8. public class Chinese implements Human {   
    9. /* (非 Javadoc)  
    10. * @see cn.com.chengang.spring.Human#eat()  
    11. */  
    12. public void eat() {   
    13. System.out.println("中國人對(duì)吃很有一套");   
    14. }   
    15.   
    16. /* (非 Javadoc)  
    17. * @see cn.com.chengang.spring.Human#walk()  
    18. */  
    19. public void walk() {   
    20. System.out.println("中國人行如飛");   
    21. }   
    22. }   
    23.   
    24. package cn.com.chengang.spring;   
    25. public class American implements Human {   
    26. /* (非 Javadoc)  
    27. * @see cn.com.chengang.spring.Human#eat()  
    28. */  
    29. public void eat() {   
    30. System.out.println("美國人主要以面包為主");   
    31. }   
    32.   
    33. /* (非 Javadoc)  
    34. * @see cn.com.chengang.spring.Human#walk()  
    35. */  
    36. public void walk() {   
    37. System.out.println("美國人以車代步,有四肢退化的趨勢");   
    38. }   
    39. }  

     

    2、對(duì)以上對(duì)象采用工廠模式的用法如下

       創(chuàng)建一個(gè)工廠類Factory,如下。這個(gè)工廠類里定義了兩個(gè)字符串常量,所標(biāo)識(shí)不同的人種。getHuman方法根據(jù)傳入?yún)?shù)的字串,來判斷要生成什么樣的人種。

    java 代碼
    1. package cn.com.chengang.spring;   
    2. public class Factory {   
    3. public final static String CHINESE = "Chinese";   
    4. public final static String AMERICAN = "American";   
    5.   
    6. public Human getHuman(String ethnic) {   
    7. if (ethnic.equals(CHINESE))   
    8. return new Chinese();   
    9. else if (ethnic.equals(AMERICAN))   
    10. return new American();   
    11. else  
    12. throw new IllegalArgumentException("參數(shù)(人種)錯(cuò)誤");   
    13. }   
    14. }  

     

    下面是一個(gè)測試的程序,使用工廠方法來得到了不同的“人種對(duì)象”,并執(zhí)行相應(yīng)的方法。

    java 代碼
    1. package cn.com.chengang.spring;   
    2. public class ClientTest {   
    3. public static void main(String[] args) {   
    4. Human human = null;   
    5. human = new Factory().getHuman(Factory.CHINESE);   
    6. human.eat();   
    7. human.walk();   
    8. human = new Factory().getHuman(Factory.AMERICAN);   
    9. human.eat();   
    10. human.walk();   
    11. }   
    12. }  

     

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

       在項(xiàng)目根目錄下創(chuàng)建一個(gè)bean.xml文件

    xml 代碼
    1. <?xml version="1.0" encoding="UTF-8"?>   
    2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">   
    3. <beans>   
    4. <bean id="Chinese" class="cn.com.chengang.spring.Chinese"/>   
    5. <bean id="American" class="cn.com.chengang.spring.American"/>   
    6. </beans>  

    修改ClientTest程序如下:

    java 代碼
    1. package cn.com.chengang.spring;   
    2. import org.springframework.context.ApplicationContext;   
    3. import org.springframework.context.support.FileSystemXmlApplicationContext;   
    4. public class ClientTest {   
    5. public final static String CHINESE = "Chinese";   
    6. public final static String AMERICAN = "American";   
    7.   
    8. public static void main(String[] args) {   
    9. // Human human = null;   
    10. // human = new Factory().getHuman(Factory.CHINESE);   
    11. // human.eat();   
    12. // human.walk();   
    13. // human = new Factory().getHuman(Factory.AMERICAN);   
    14. // human.eat();   
    15. // human.walk();   
    16.   
    17. ApplicationContext ctx = new FileSystemXmlApplicationContext("bean.xml");   
    18. Human human = null;   
    19. human = (Human) ctx.getBean(CHINESE);   
    20. human.eat();   
    21. human.walk();   
    22. human = (Human) ctx.getBean(AMERICAN);   
    23. human.eat();   
    24. human.walk();   
    25. }   
    26. }  

     從這個(gè)程序可以看到,ctx就相當(dāng)于原來的Factory工廠,原來的Factory就可以刪除掉了。然后又把Factory里的兩個(gè)常量移到了ClientTest類里,整個(gè)程序結(jié)構(gòu)基本一樣。

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

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

       id就是ctx.getBean的參數(shù)值,一個(gè)字符串。class就是一個(gè)類(包名+類名)。然后在ClientTest類里獲得Chinese對(duì)象就是這么一句

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

       因?yàn)間etBean方法返回的是Object類型,所以前面要加一個(gè)類型轉(zhuǎn)換。

       總結(jié)

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

       舉個(gè)例子,如果用戶需求發(fā)生變化,要把Chinese類修改一下。那么前一種工廠模式,就要更改Factory類的方法,并且重新編譯布署。而IoC只需要將class屬性改變一下,并且由于IoC利用了Java反射機(jī)制,這些對(duì)象是動(dòng)態(tài)生成的,這時(shí)我們就可以熱插撥Chinese對(duì)象(不必把原程序停止下來重新編譯布署)

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

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

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

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

       另外,bean.xml也可以改成其他名字。這樣我們?cè)谙到y(tǒng)中就可以分門別類的設(shè)置不同的bean.xml。

       (4)關(guān)于IoC的低侵入性。

       什么是低侵入性?如果你用過Struts或EJB就會(huì)發(fā)現(xiàn),要繼承一些接口或類,才能利用它們的框架開發(fā)。這樣,系統(tǒng)就被綁定在Struts、EJB上了,對(duì)系統(tǒng)的可移植性產(chǎn)生不利的影響。如果代碼中很少涉及某一個(gè)框架的代碼,那么這個(gè)框架就可以稱做是一個(gè)低侵入性的框架。

       Spring的侵入性很低,Humen.java、Chinese.java等幾個(gè)類都不必繼承什么接口或類。但在ClientTest里還是有一些Spring的影子:FileSystemXmlApplicationContext類和ctx.getBean方式等。
    現(xiàn)在,低侵入性似乎也成了判定一個(gè)框架的實(shí)現(xiàn)技術(shù)好壞的標(biāo)準(zhǔn)之一。

       (5)關(guān)于bean.xml的用法

       bean.xml的用法還有很多,其中內(nèi)容是相當(dāng)豐富的。假設(shè)Chinese類里有一個(gè)humenName屬性(姓名),那么原的bean.xml修改如下。此后生成Chinese對(duì)象時(shí),“陳剛”這個(gè)值將自動(dòng)設(shè)置到Chinese類的humenName屬性中。而且由于singleton為true這時(shí)生成Chinese對(duì)象將采用單例模式,系統(tǒng)僅存在一個(gè)Chinese對(duì)象實(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的文檔一看就明白了。

     Spring能有效地組織J2EE應(yīng)用各層的對(duì)象。不管是控制層的Action對(duì)象,還是業(yè)務(wù)層的Service對(duì)象,還是持久層的DAO對(duì)象,都可在Spring的管理下有機(jī)地協(xié)調(diào)、運(yùn)行。Spring將各層的對(duì)象以松耦合的方式組織在一起,Action對(duì)象無須關(guān)心Service對(duì)象的具體實(shí)現(xiàn),Service對(duì)象無須關(guān)心持久層對(duì)象的具體實(shí)現(xiàn),各層對(duì)象的調(diào)用完全面向接口。當(dāng)系統(tǒng)需要重構(gòu)時(shí),代碼的改寫量將大大減少。

      上面所說的一切都得宜于Spring的核心機(jī)制,依賴注入。依賴注入讓bean與bean之間以配置文件組織在一起,而不是以硬編碼的方式耦合在一起。理解依賴注入

      依賴注入(Dependency Injection)和控制反轉(zhuǎn)(Inversion of Control)是同一個(gè)概念。具體含義是:當(dāng)某個(gè)角色(可能是一個(gè)Java實(shí)例,調(diào)用者)需要另一個(gè)角色(另一個(gè)Java實(shí)例,被調(diào)用者)的協(xié)助時(shí),在傳統(tǒng)的程序設(shè)計(jì)過程中,通常由調(diào)用者來創(chuàng)建被調(diào)用者的實(shí)例。但在Spring里,創(chuàng)建被調(diào)用者的工作不再由調(diào)用者來完成,因此稱為控制反轉(zhuǎn);創(chuàng)建被調(diào)用者實(shí)例的工作通常由Spring容器來完成,然后注入調(diào)用者,因此也稱為依賴注入。

      不管是依賴注入,還是控制反轉(zhuǎn),都說明Spring采用動(dòng)態(tài)、靈活的方式來管理各種對(duì)象。對(duì)象與對(duì)象之間的具體實(shí)現(xiàn)互相透明。在理解依賴注入之前,看如下這個(gè)問題在各種社會(huì)形態(tài)里如何解決:一個(gè)人(Java實(shí)例,調(diào)用者)需要一把斧子(Java實(shí)例,被調(diào)用者)。

      (1)原始社會(huì)里,幾乎沒有社會(huì)分工。需要斧子的人(調(diào)用者)只能自己去磨一把斧子(被調(diào)用者)。對(duì)應(yīng)的情形為:Java程序里的調(diào)用者自己創(chuàng)建被調(diào)用者。

      (2)進(jìn)入工業(yè)社會(huì),工廠出現(xiàn)。斧子不再由普通人完成,而在工廠里被生產(chǎn)出來,此時(shí)需要斧子的人(調(diào)用者)找到工廠,購買斧子,無須關(guān)心斧子的制造過程。對(duì)應(yīng)Java程序的簡單工廠的設(shè)計(jì)模式。

      (3)進(jìn)入“按需分配”社會(huì),需要斧子的人不需要找到工廠,坐在家里發(fā)出一個(gè)簡單指令:需要斧子。斧子就自然出現(xiàn)在他面前。對(duì)應(yīng)Spring的依賴注入。

      第一種情況下,Java實(shí)例的調(diào)用者創(chuàng)建被調(diào)用的Java實(shí)例,必然要求被調(diào)用的Java類出現(xiàn)在調(diào)用者的代碼里。無法實(shí)現(xiàn)二者之間的松耦合。

      第二種情況下,調(diào)用者無須關(guān)心被調(diào)用者具體實(shí)現(xiàn)過程,只需要找到符合某種標(biāo)準(zhǔn)(接口)的實(shí)例,即可使用。此時(shí)調(diào)用的代碼面向接口編程,可以讓調(diào)用者和被調(diào)用者解耦,這也是工廠模式大量使用的原因。但調(diào)用者需要自己定位工廠,調(diào)用者與特定工廠耦合在一起。

      第三種情況下,調(diào)用者無須自己定位工廠,程序運(yùn)行到需要被調(diào)用者時(shí),系統(tǒng)自動(dòng)提供被調(diào)用者實(shí)例。事實(shí)上,調(diào)用者和被調(diào)用者都處于Spring的管理下,二者之間的依賴關(guān)系由Spring提供。

      所謂依賴注入,是指程序運(yùn)行過程中,如果需要調(diào)用另一個(gè)對(duì)象協(xié)助時(shí),無須在代碼中創(chuàng)建被調(diào)用者,而是依賴于外部的注入。Spring的依賴注入對(duì)調(diào)用者和被調(diào)用者幾乎沒有任何要求,完全支持對(duì)POJO之間依賴關(guān)系的管理。依賴注入通常有兩種:

      ·設(shè)值注入。

      ·構(gòu)造注入。
    .......

    posted on 2009-04-06 00:13 lanxin1020 閱讀(724) 評(píng)論(0)  編輯  收藏 所屬分類: spring
    主站蜘蛛池模板: 亚洲av无码一区二区三区天堂古代| 最近最好的中文字幕2019免费| 在线观看国产情趣免费视频| 久久精品国产亚洲AV网站| 高h视频在线免费观看| 国产精品视频永久免费播放| 亚洲av日韩av无码| 中文成人久久久久影院免费观看 | 亚洲成av人片天堂网老年人| 亚洲成aⅴ人片在线观| 97青青草原国产免费观看| a级亚洲片精品久久久久久久| 亚洲日韩在线中文字幕综合| 久久不见久久见免费影院| 亚洲精品456在线播放| 亚欧国产一级在线免费| 成人毛片18女人毛片免费| 亚洲国产精品日韩在线| 在人线av无码免费高潮喷水| 亚洲成人免费电影| 久久精品a一国产成人免费网站| 亚洲国产成人精品无码一区二区 | 亚洲成AV人片在WWW色猫咪| 国产日韩久久免费影院| 午夜时刻免费入口| 亚洲A∨精品一区二区三区下载| 国产成人一区二区三区免费视频| 2020久久精品亚洲热综合一本| 91网站免费观看| 亚洲乱亚洲乱妇无码| 日韩免费视频在线观看| 深夜a级毛片免费视频| 亚洲免费视频一区二区三区| xvideos永久免费入口| 日韩亚洲欧洲在线com91tv| 九九精品成人免费国产片| 久久久久亚洲av无码专区| 国产香蕉免费精品视频| 亚洲欧洲无码一区二区三区| 性做久久久久免费看| 久久av免费天堂小草播放|