1、概念理解
對(duì)Spring耳聞已久,但一直沒(méi)有時(shí)間和心情去看它,最近它的聲音是越來(lái)越大了,Java視線http://forum.javaeye.com/有不高手在談?wù)撍S谑浅弥锌臻e時(shí)間,我也花了兩個(gè)晚上看了看Spring,看的是夏昕的<Spring開(kāi)發(fā)指南>http://www.xiaxin.net/Spring_Dev_Guide.rar,文章寫(xiě)得不錯(cuò)。以下談?wù)勎业膶W(xué)習(xí)感受
一、Spring的IoC(Inversion of Control)。
這是Spring中得有特點(diǎn)的一部份。IoC又被翻譯成“控制反轉(zhuǎn)”,也不知道是誰(shuí)翻譯得這么別扭,感覺(jué)很深?yuàn)W的詞。其實(shí),原理很簡(jiǎn)單,用一句通俗的話(huà)來(lái)說(shuō):就是用XML來(lái)定義生成的對(duì)象。IoC其實(shí)是一種設(shè)計(jì)模式,Spring只是實(shí)現(xiàn)了這種設(shè)計(jì)模式。
這種設(shè)計(jì)模式是怎么來(lái)的呢?是實(shí)踐中逐漸形成的。
第一階段:用普通的無(wú)模式來(lái)寫(xiě)Java程序。一般初學(xué)者都要經(jīng)過(guò)這個(gè)階段。
第二階段:頻繁的開(kāi)始使用接口,這時(shí),接口一般都會(huì)伴隨著使用工廠模式。
第三階段:使用IoC模式。工廠模式還不夠好:(1)因?yàn)榈念?lèi)的生成代碼寫(xiě)死在程序里,如果你要換一個(gè)子類(lèi),就要修改工廠方法。(2)一個(gè)接口常常意味著一個(gè)生成工廠,會(huì)多出很多工廠類(lèi)。
可以把IoC模式看做是工廠模式的升華,可以把IoC看作是一個(gè)大工廠,只不過(guò)這個(gè)大工廠里要生成的對(duì)象都是在XML文件中給出定義的,然后利用Java的“反射”編程,根據(jù)XML中給出的類(lèi)名生成相應(yīng)的對(duì)象。從實(shí)現(xiàn)來(lái)看,IoC是把以前在工廠方法里寫(xiě)死的對(duì)象生成代碼,改變?yōu)橛蒟ML文件來(lái)定義,也就是把工廠和對(duì)象生成這兩者獨(dú)立分隔開(kāi)來(lái),目的就是提高靈活性和可維護(hù)性。
IoC中最基本的Java技術(shù)就是“反射”編程。反射又是一個(gè)生澀的名詞,通俗的說(shuō)反射就是根據(jù)給出的類(lèi)名(字符串)來(lái)生成對(duì)象。這種編程方式可以讓對(duì)象在生成時(shí)才決定要生成哪一種對(duì)象。我在最近的一個(gè)項(xiàng)目也用到了反射,當(dāng)時(shí)是給出一個(gè).properties文本文件,里面寫(xiě)了一些全類(lèi)名(包名+類(lèi)名),然后,要根據(jù)這些全類(lèi)名在程序中生成它們的對(duì)象。反射的應(yīng)用是很廣泛的,象Hibernate、String中都是用“反射”做為最基本的技術(shù)手段。
在過(guò)去,反射編程方式相對(duì)于正常的對(duì)象生成方式要慢10幾倍,這也許也是當(dāng)時(shí)為什么反射技術(shù)沒(méi)有普通應(yīng)用開(kāi)來(lái)的原因。但經(jīng)SUN改良優(yōu)化后,反射方式生成對(duì)象和通常對(duì)象生成方式,速度已經(jīng)相差不大了(但依然有一倍以上的差距)。
所以要理解IoC,你必須先了解工廠模式和反射編程,否則對(duì)它產(chǎn)生的前因后果和實(shí)現(xiàn)原理都是無(wú)法理解透徹的。只要你理解了這一點(diǎn),你自己也完全可以自己在程序中實(shí)現(xiàn)一個(gè)IoC框架,只不是這還要涉及到XML解析等其他知識(shí),稍微麻煩一些。
IoC最大的好處是什么?因?yàn)榘褜?duì)象生成放在了XML里定義,所以當(dāng)我們需要換一個(gè)實(shí)現(xiàn)子類(lèi)將會(huì)變成很簡(jiǎn)單(一般這樣的對(duì)象都是現(xiàn)實(shí)于某種接口的),只要修改XML就可以了,這樣我們甚至可以實(shí)現(xiàn)對(duì)象的熱插撥(有點(diǎn)象USB接口和SCIS硬盤(pán)了)。
IoC最大的缺點(diǎn)是什么?(1)生成一個(gè)對(duì)象的步驟變復(fù)雜了(其實(shí)上操作上還是挺簡(jiǎn)單的),對(duì)于不習(xí)慣這種方式的人,會(huì)覺(jué)得有些別扭和不直觀。(2)對(duì)象生成因?yàn)槭鞘褂梅瓷渚幊蹋谛噬嫌行p耗。但相對(duì)于IoC提高的維護(hù)性和靈活性來(lái)說(shuō),這點(diǎn)損耗是微不足道的,除非某對(duì)象的生成對(duì)效率要求特別高。(3)缺少I(mǎi)DE重構(gòu)操作的支持,如果在Eclipse要對(duì)類(lèi)改名,那么你還需要去XML文件里手工去改了,這似乎是所有XML方式的缺憾所在。
總的來(lái)說(shuō)IoC無(wú)論原理和實(shí)現(xiàn)都還算是很簡(jiǎn)單的。一些人曾認(rèn)為IoC沒(méi)什么實(shí)際作用,這種說(shuō)法是可以理解的,因?yàn)槿绻阍诰幊讨泻苌偈褂媒涌冢蚝苌偈褂霉S模式,那么你根本就沒(méi)有使用IoC的強(qiáng)烈需要,也不會(huì)體會(huì)到IoC可貴之處。有些人也說(shuō)要消除工廠模式、單例模式,但是都語(yǔ)焉不詳、人云亦云。但如果你看到IoC模式和用上Spring,那么工廠模式和單例模式的確基本上可以不用了。但它消失了嗎?沒(méi)有!Spring的IoC實(shí)現(xiàn)本身就是一個(gè)大工廠,其中也包含了單例對(duì)象生成方式,只要用一個(gè)設(shè)置就可以讓對(duì)象生成由普通方式變單一實(shí)例方式,非常之簡(jiǎn)單。
總結(jié):
(1)IoC原理很簡(jiǎn)單,作用的針對(duì)性也很強(qiáng),不要把它看得很玄乎。
(2)要理解IoC,首先要了解“工廠、接口、反射”這些概念。
二、Spring的MVC
如果你已經(jīng)熟悉Struts,那么不必把MVC做為重點(diǎn)學(xué)習(xí)內(nèi)容。基本上我認(rèn)為Spring MVC是一個(gè)雞肋,它的技術(shù)上很先進(jìn),但易用性上沒(méi)有Struts好。而且Struts有這么多年的基礎(chǔ)了,Spring很難取代Struts的地位。這就是先入為主的優(yōu)秀,一個(gè)項(xiàng)目經(jīng)理選用一種框架,不能單純的從它的技術(shù)上考慮,還有開(kāi)發(fā)效率,人員配置等都是考慮因素。但做為研究性的學(xué)習(xí),Spring的MVC部份還是蠻有價(jià)值的。
三、數(shù)據(jù)庫(kù)層的模板
Spring主要是提供了一些數(shù)據(jù)庫(kù)模板(模板也是一種Java設(shè)計(jì)模式),讓數(shù)據(jù)部分的代碼更簡(jiǎn)潔,那些try...catch都可以不見(jiàn)了。這個(gè)的確是個(gè)好東東。
四、AOP
AOP又稱(chēng)面向方面編程,它的實(shí)現(xiàn)原理還是用了反射:通過(guò)對(duì)某一個(gè)種類(lèi)的方法名做監(jiān)控來(lái)實(shí)現(xiàn)統(tǒng)一處理。比如:監(jiān)控以“insert”字符串開(kāi)頭的方法名,在這種方法執(zhí)行的前后進(jìn)行某種處理(數(shù)據(jù)庫(kù)事務(wù)等)。但這里我有一個(gè)疑問(wèn)?不一定所有以insert開(kāi)頭的方法都是數(shù)據(jù)庫(kù)操作,哪么當(dāng)某個(gè)insert開(kāi)頭的方法不是數(shù)據(jù)庫(kù)操作,你又對(duì)它進(jìn)行了數(shù)據(jù)事務(wù)的操作,這樣的錯(cuò)誤如何防止???我對(duì)這方面了解不深,還是只知道一個(gè)大概。
曾看過(guò)一個(gè)程序員發(fā)出這樣的感慨:“框架一個(gè)接一個(gè),學(xué)也學(xué)不完,而且有必要嗎?這樣一層層的加上框架,還不如直接寫(xiě)JSP來(lái)得直接,效率還高”。我想這種困惑很多人都有吧?但如果你經(jīng)過(guò)的項(xiàng)目漸多,就會(huì)發(fā)現(xiàn),維護(hù)項(xiàng)目要比開(kāi)發(fā)項(xiàng)目更艱難,代價(jià)更大。那種用JSP直接來(lái)寫(xiě),層次又不清楚的開(kāi)發(fā),往往最后得到一個(gè)不可再修改的軟件,一團(tuán)亂麻,移一發(fā)而動(dòng)全身。但軟件不象電視機(jī),做好了就不會(huì)改動(dòng)了,軟件是一個(gè)變化的事物,用戶(hù)的需求隨時(shí)會(huì)改變,這時(shí)你會(huì)體會(huì)到分層和使用框架的好處了,它們?yōu)槟阕隽塑浖泻芏嗪蜆I(yè)務(wù)無(wú)關(guān)的工作,你可以只關(guān)注業(yè)務(wù),并減少代碼量。唯一缺點(diǎn)就是有一個(gè)學(xué)習(xí)的代價(jià),框架配置上也較麻煩。
學(xué)習(xí)框架,我認(rèn)為應(yīng)該:第一步,了解這個(gè)框架中的一些關(guān)鍵概念,它的具體含義是什么。第二步,了解這個(gè)框架的精華在哪里,它能對(duì)開(kāi)發(fā)起到什么樣的作用,最好能對(duì)它的原理有一定的了解。第三步,用這個(gè)框架來(lái)寫(xiě)幾個(gè)例子,實(shí)際體會(huì)一下。我現(xiàn)在還是剛剛大概完成了前兩步,這幾天會(huì)再看看Spring的文檔并用Spring寫(xiě)幾個(gè)例子,到時(shí)一起發(fā)出來(lái)。
另外,很贊賞<Spring開(kāi)發(fā)指南>的作者夏昕的觀點(diǎn),將自已的經(jīng)驗(yàn)寫(xiě)成文檔公開(kāi)出來(lái),不過(guò)一個(gè)人的力量終究太弱。最好能夠形成一個(gè)組織,對(duì)一種新技術(shù),由一兩個(gè)人出一個(gè)大綱,大家把它分了,更寫(xiě)一章,然后由兩三個(gè)人總集起。我個(gè)人感覺(jué),由于英文語(yǔ)言的關(guān)系,新技術(shù)引進(jìn)到國(guó)內(nèi)的還是太慢了,至少要比國(guó)外慢上一年以上,成立一個(gè)開(kāi)源文檔組織還是很有意義的事。