玩玩Spring之IOC(一)(轉載)

          ???? Spring的功能是很強大的,在其“絕不發明自己認為好的輪子,而只發明自己認為不好的輪子”的指導思想下,通過充分實踐了“一切實事求是、‘循證架構’的工作方式”的理論,基本上把輕量級的J2EE應用框架(如ORM、MVC等)進行了整合,并構架了一些常用的功能(如DAO),形成了一個功能強大的J2EE輕量級企業應用框架。
            然而,或許是大家對Spring掌握得還不透徹的緣故吧,看到很多軟件企業中用到的Spring功能,基本上大多數都只是用其IOC功能,有時候附帶用了其中的AOP事務管理功能。
            IOC及AOP雖然不是Spring首創,然而其在這兩塊都是做得很不錯的,應該說整個Spring框架就是圍繞著其IOC實現及AOP實現架設起來的。我想,深入挖掘IOC、AOP以及Spring中的實現,使用等,對于初學者幫助會非常大,因此,從本期開始,大峽的《玩玩Spring系列》將伴隨大家一起走進IOC及AOP的世界。
            由于本人水平有限,文中難免有很多不足甚至錯誤之處,還請各位朋友不吝批評指教。
          ?
          一、IOC簡介
            IOC-全稱Inversion?of?Control,中文解釋:控制反轉。另外,IOC又稱DI(全稱)Dependency?Injection,中文解釋:依賴注入。
            呵呵,這些名詞搞得有點像學古文的味道哈。很多大師還都說IOC中有一個著名的好萊塢理論:你呆著別動,到時我會找你。你呆著別動,到時我會找你。由于本人未到過好萊塢參加過社會實踐,因此,這句話理解有點困難。
            IOC是一種新的設計模式,即IOC模式,系統中通過引入實現了IOC模式的IOC容器,即可由IOC容器來管理對象的生命周期、依賴關系等,從而使得應用程序的配置和依賴性規范與實際的應用程序代碼分開。其中一個特點就是通過文本的配件文件進行應用程序組件間相互關系的配置,而不用重新修改并編譯具體的Java代碼。
            當前比較知名的IOC容器有:Pico?Container、Avalon?、Spring、JBoss、HiveMind、EJB等,國內由板橋里人負責的國產開源項目Jdon框架,也是具有IOC容器功能(由于沒來得及認真研讀其源碼,似乎jdon中IOC部份是調用Pico的IOC容器功能來實現的)。
            在上面的幾個IOC容器中,輕量級的有Pico?Container、Avalon、Spring、HiveMind等,超重量級的有EJB,而半輕半重的有容器有JBoss,Jdon等。
            
            IOC究竟是什么?IOC是如何產生的?用在什么場合?為什么我們以前不用IOC,而現在要用IOC?“物有本末,事有終始”,為了更加透徹的理解這一問題,大峽打算從自己所理解的面向對象(OO)設計及編程發展歷程來進行分析,也許這樣能讓IOC的初學者更加了解IOC的發展的前因后果,爭取做到“知其然,知其所以然,使其然!”。
            若大家等不急了,就直接百度一下有關IOC的其它文章,這方面國內很多先驅們已經作了很多介紹。如冰云的《IOC詳解》、板橋里人的設計模式及IOC理論等。
          ?
          二、?最老的OO編程
            記得曾經看《Think?in?Java》最早版本的時候,里面有這么一句讓人振奮話:一切都是對象。這時我們OO編程的核心是圍繞著面向對象編程的三個特性即“繼承”、“封裝”、“多態”來展開的。
          2.1?封裝
            那時我們學會了對現實就的事物及軟件模型進行了抽象。比如要描述一只貓,那么這支貓應該有“顏色”、“重量”、“公母”、“脾氣”、“出生日期”等屬性,另外還有“跑”、“吃”、“叫”、“貓捉老鼠”等方法。如Java代碼來表示,大致就是如下:
          public?Class?Cat
          {
          private?String?color;//顏色
          private?String?weight;//重量
          private?String?sex;//公母
          private?String?temper;//脾氣
          private?String?birthday;//出生日期
          private?void?run?();//跑
          private?void?eat?(Food?food);?//吃(食物)
          private?void?shout(int?type);//叫(類別)
          private?boolean?chase(Mice?mice);//貓捉老鼠
          }
          ?
          2.2?繼承
            最早的OO編程時期,我們還會引入繼承,還經常鼓勵大家多用繼續,認為繼承就是OO編程思想的核心。繼承的核心就是圍繞著如何把類與類之間具有共同特性的部份抽象到基類中。認為這樣不但能使用了OO的特性,還減少了很多子類的代碼。
            我們通過日常生活的常識知道,貓是一種動物,因此動物有的特性他基本上都有。于是,如果我們的系統中不但有貓,還會有很多其它的動物出現。我們就會設計一個動物類,把所有動物的共性抽象到一個基類中。這里,貓及動物基類的代碼大致如下:
          public?abstract?Class?Animal{
          private?String?color;//顏色
          private?String?weight;//重量
          private?String?sex;//公母
          private?String?temper;//脾氣
          private?String?birthday;//出生日期
          private?void?run?();//跑
          private?void?eat?(Food?food);?//吃(食物)
          private?void?shout(int?type);//叫(類別)
          }
          public?Class?Cat?extends?Animal
          ?private?int?power;//能力
          ?private?int?agility;//敏捷度
          ???//??貓捉老鼠是特有的方法
          ?private?boolean?chase(Mice?mice)?{
          ??return?true;
          ?};
          }
          ?
          ?
          2.3?多態
            這時我們還會不時使用到OO的另外一個特性多態。多態是很重要的一門技術,然而很多時候卻沒有很好的理解并使用,回頭看以前的代碼,我們看到有很多地方屬于故弄玄虛的嫌疑。
            接上面的例子,假如我們要寫一個喂養寵物(有貓、狗、豬、豹、老鼠等)的程序。利用Java的多態特性,我們的大致代碼如下:
          public?class?PetManage?{
          ?//喂食我的寵物
          ?public?void?feeding(Animal?a)
          ?{??
          ?}?
          ?/**
          ??*?@param?args
          ??*/
          ?public?static?void?main(String[]?args)?{?
          ??Animal?myPet=new?Cat();
          ??PetManage?pm=new?PetManage();?????
          ??pm.feeding(myPet);
          ?}
          }
            通過使用多態特性,哪一天若我們的不喜歡貓,而是喜歡養豬的時候,只要把new?Cat()變成new?Pig(),即可。
          ?
          2.4?對象生命周期
            這一階段的OO程序中,我們知道要用一個對象的時候,就要使用Java中的關鍵字new來生成一個來用即可。OO對于我們來說,一切都是那么簡單,很多時候甚至感覺OO跟OP的編程方法也沒太大區別。代碼如下:
          Cat?myCat=new?Cat();//創建一支具體的貓
          myCat.shout();//叫一聲
            此時,我們對Java虛擬是非常信任的,我們的思想也很單純,我們知道Java對象的生命開始于new關鍵詞。我們不太關心對象生命的結束,我們知道Java有一個比C語言歷害、智能化的垃圾收集器,他會幫我們自己的清理內存中不用的對象。
            當然,也有的人由于對垃圾收集器忠誠度的懷疑,不放心垃圾收集器的能力,于是在程序中經常要加一句類似“myPet=null”的代碼來結束對象的生命。
            當然,我們也知道有一些外部資源如數據庫連接等,需要手動熟悉資源。于是知道在使用類似資源的時候必須都加上一句:conn.close(),有時候還要在close()后面再加一句:conn=null。呵呵,非常有意思。
          ?
          2.5小結
            現在看來,其實那時確實犯了很多幼稚的錯誤,也走了不少的彎路,做了很多畫蛇添足的工作,寫了很多難與維護的代碼。
            對比今天的IOC模式,若要從早的OO方法中硬要找一個類似Spring的容器的話,那就是:“程序員+JVM本身”。是程序員以及JVM一起我們管理對象的生命周期、對象之間的關系等。那時候若有任何變動都需要改代碼,(雖然好的設計代碼修改會非常少,但也得改!),然后編譯,然后拿到測試環境及用戶環境中執行。如此反復,年日復一日、年復一年。
            那時我們的代碼復用用得最多的就是OO的繼承功能,另外還有很多OP方法中帶過來的函數。
            本文中涉及到的幾個簡單源碼,請到EasyJF開源團隊官網下載,地址:
            http://www.easyjf.com/html/bbs/20060602/12718636-1843943.htm?ejid=1287314863003738
          ?
            


          posted on 2006-06-09 11:57 nbt 閱讀(210) 評論(0)  編輯  收藏 所屬分類: Spring框架

          <2006年6月>
          28293031123
          45678910
          11121314151617
          18192021222324
          2526272829301
          2345678

          導航

          統計

          常用鏈接

          留言簿(3)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          相冊

          收藏夾

          Java技術網站

          友情鏈接

          國內一些開源網站

          最新隨筆

          搜索

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 定州市| 鱼台县| 姚安县| 土默特左旗| 淮安市| 沁源县| 溆浦县| 郯城县| 溧水县| 铁岭县| 平和县| 盘山县| 肃宁县| 彭州市| 青冈县| 任丘市| 亚东县| 平邑县| 阿克| 永胜县| 海盐县| 特克斯县| 高密市| 西宁市| 磴口县| 齐河县| 犍为县| 宣武区| 巴林左旗| 莱西市| 南康市| 岑巩县| 临夏县| 依安县| 泰宁县| 南丰县| 吉林省| 大同市| 萨嘎县| 江达县| 兴宁市|