Spring的功能是很強(qiáng)大的,在其“絕不發(fā)明自己認(rèn)為好的輪子,而只發(fā)明自己認(rèn)為不好的輪子”的指導(dǎo)思想下,通過充分實踐了“一切實事求是、‘循證架構(gòu)’的工作方式”的理論,基本上把輕量級的J2EE應(yīng)用框架(如ORM、MVC等)進(jìn)行了整合,并構(gòu)架了一些常用的功能(如DAO),形成了一個功能強(qiáng)大的J2EE輕量級企業(yè)應(yīng)用框架。
然而,或許是大家對Spring掌握得還不透徹的緣故吧,看到很多軟件企業(yè)中用到的Spring功能,基本上大多數(shù)都只是用其IOC功能,有時候附帶用了其中的AOP事務(wù)管理功能。
IOC及AOP雖然不是Spring首創(chuàng),然而其在這兩塊都是做得很不錯的,應(yīng)該說整個Spring框架就是圍繞著其IOC實現(xiàn)及AOP實現(xiàn)架設(shè)起來的。我想,深入挖掘IOC、AOP以及Spring中的實現(xiàn),使用等,對于初學(xué)者幫助會非常大,因此,從本期開始,大峽的《玩玩Spring系列》將伴隨大家一起走進(jìn)IOC及AOP的世界。
由于本人水平有限,文中難免有很多不足甚至錯誤之處,還請各位朋友不吝批評指教。
?
一、IOC簡介
IOC-全稱Inversion of Control,中文解釋:控制反轉(zhuǎn)。另外,IOC又稱DI(全稱)Dependency Injection,中文解釋:依賴注入。
呵呵,這些名詞搞得有點像學(xué)古文的味道哈。很多大師還都說IOC中有一個著名的好萊塢理論:你呆著別動,到時我會找你。由于本人未到過好萊塢參加過社會實踐,因此,這句話理解有點困難。
IOC是一種新的設(shè)計模式,即IOC模式,系統(tǒng)中通過引入實現(xiàn)了IOC模式的IOC容器,即可由IOC容器來管理對象的生命周期、依賴關(guān)系等,從而使得應(yīng)用程序的配置和依賴性規(guī)范與實際的應(yīng)用程序代碼分開。其中一個特點就是通過文本的配件文件進(jìn)行應(yīng)用程序組件間相互關(guān)系的配置,而不用重新修改并編譯具體的Java代碼。
當(dāng)前比較知名的IOC容器有:Pico Container、Avalon 、Spring、JBoss、HiveMind、EJB等,國內(nèi)由板橋里人負(fù)責(zé)的國產(chǎn)開源項目Jdon框架,也是具有IOC容器功能(由于沒來得及認(rèn)真研讀其源碼,似乎jdon中IOC部份是調(diào)用Pico的IOC容器功能來實現(xiàn)的)。
在上面的幾個IOC容器中,輕量級的有Pico Container、Avalon、Spring、HiveMind等,超重量級的有EJB,而半輕半重的有容器有JBoss,Jdon等。
IOC究竟是什么?IOC是如何產(chǎn)生的?用在什么場合?為什么我們以前不用IOC,而現(xiàn)在要用IOC?“物有本末,事有終始”,為了更加透徹的理解這一問題,大峽打算從自己所理解的面向?qū)ο?OO)設(shè)計及編程發(fā)展歷程來進(jìn)行分析,也許這樣能讓IOC的初學(xué)者更加了解IOC的發(fā)展的前因后果,爭取做到“知其然,知其所以然,使其然!”。
若大家等不急了,就直接百度一下有關(guān)IOC的其它文章,這方面國內(nèi)很多先驅(qū)們已經(jīng)作了很多介紹。如冰云的《IOC詳解》、板橋里人的設(shè)計模式及IOC理論等。
?
二、?最老的OO編程
記得曾經(jīng)看《Think in Java》最早版本的時候,里面有這么一句讓人振奮話:一切都是對象。這時我們OO編程的核心是圍繞著面向?qū)ο缶幊痰娜齻€特性即“繼承”、“封裝”、“多態(tài)”來展開的。
2.1 封裝
那時我們學(xué)會了對現(xiàn)實就的事物及軟件模型進(jìn)行了抽象。比如要描述一只貓,那么這支貓應(yīng)該有“顏色”、“重量”、“公母”、“脾氣”、“出生日期”等屬性,另外還有“跑”、“吃”、“叫”、“貓捉老鼠”等方法。如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編程時期,我們還會引入繼承,還經(jīng)常鼓勵大家多用繼續(xù),認(rèn)為繼承就是OO編程思想的核心。繼承的核心就是圍繞著如何把類與類之間具有共同特性的部份抽象到基類中。認(rèn)為這樣不但能使用了OO的特性,還減少了很多子類的代碼。
我們通過日常生活的常識知道,貓是一種動物,因此動物有的特性他基本上都有。于是,如果我們的系統(tǒng)中不但有貓,還會有很多其它的動物出現(xiàn)。我們就會設(shè)計一個動物類,把所有動物的共性抽象到一個基類中。這里,貓及動物基類的代碼大致如下:
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 多態(tài)
這時我們還會不時使用到OO的另外一個特性多態(tài)。多態(tài)是很重要的一門技術(shù),然而很多時候卻沒有很好的理解并使用,回頭看以前的代碼,我們看到有很多地方屬于故弄玄虛的嫌疑。
接上面的例子,假如我們要寫一個喂養(yǎng)寵物(有貓、狗、豬、豹、老鼠等)的程序。利用Java的多態(tài)特性,我們的大致代碼如下:
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);
?}
}
通過使用多態(tài)特性,哪一天若我們的不喜歡貓,而是喜歡養(yǎng)豬的時候,只要把new Cat()變成new Pig(),即可。
2.4 對象生命周期
這一階段的OO程序中,我們知道要用一個對象的時候,就要使用Java中的關(guān)鍵字new來生成一個來用即可。OO對于我們來說,一切都是那么簡單,很多時候甚至感覺OO跟OP的編程方法也沒太大區(qū)別。代碼如下:
Cat myCat=new Cat();//創(chuàng)建一支具體的貓
myCat.shout();//叫一聲
此時,我們對Java虛擬是非常信任的,我們的思想也很單純,我們知道Java對象的生命開始于new關(guān)鍵詞。我們不太關(guān)心對象生命的結(jié)束,我們知道Java有一個比C語言歷害、智能化的垃圾收集器,他會幫我們自己的清理內(nèi)存中不用的對象。
當(dāng)然,也有的人由于對垃圾收集器忠誠度的懷疑,不放心垃圾收集器的能力,于是在程序中經(jīng)常要加一句類似“myPet=null”的代碼來結(jié)束對象的生命。
當(dāng)然,我們也知道有一些外部資源如數(shù)據(jù)庫連接等,需要手動熟悉資源。于是知道在使用類似資源的時候必須都加上一句:conn.close(),有時候還要在close()后面再加一句:conn=null。呵呵,非常有意思。
?
2.5小結(jié)
現(xiàn)在看來,其實那時確實犯了很多幼稚的錯誤,也走了不少的彎路,做了很多畫蛇添足的工作,寫了很多難與維護(hù)的代碼。
對比今天的IOC模式,若要從早的OO方法中硬要找一個類似Spring的容器的話,那就是:“程序員+JVM本身”。是程序員以及JVM一起我們管理對象的生命周期、對象之間的關(guān)系等。那時候若有任何變動都需要改代碼,(雖然好的設(shè)計代碼修改會非常少,但也得改!),然后編譯,然后拿到測試環(huán)境及用戶環(huán)境中執(zhí)行。如此反復(fù),年日復(fù)一日、年復(fù)一年。
那時我們的代碼復(fù)用用得最多的就是OO的繼承功能,另外還有很多OP方法中帶過來的函數(shù)。
?
本文中涉及到的幾個簡單源碼,請到EasyJF開源團(tuán)隊官網(wǎng)下載,地址:
?
下期預(yù)告:OO編程的第二階段,設(shè)計模式的廣泛應(yīng)用。
(
備注:由于筆者不想拐彎抹角浪費大家玩的時間,有些“表白”難免過于直接,還請不喜歡Spring或者過分喜歡Spring的同行多多見諒! 本文中的“我們”,僅指與筆者有著同樣成長經(jīng)歷的80后人,對于文章提到的觀點,多數(shù)皆屬于筆者個人觀點,不代表任何人。
本文作者:
EasyJF開源團(tuán)隊大峽 版權(quán)歸
EasyJF開源團(tuán)隊所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請保留作者版權(quán)聲明,謝謝!)
?
附