?
幾天前,在Don Box的博客上,我設法回答一個問題"Spring比EJB簡單嗎?".現(xiàn)在,這個問題像是有些多余了,因為Spring和EJB的目標并不完全一致,但也許從EJB和Spring兩者所共有之處來回答,是可以的。Ted Neward在他的博客上對我的回復進行了評論,我現(xiàn)在去回應一下他的觀點。
Ted評論:Spring是一個比EJB簡單多了的框架,因為Spring更多是用基于POJO(PlainObject Old Object)的方案,但對于"一些情況"下,它并不簡單,而是更復雜。
Rod:好的,在"一些情況"下,地球是扁平的對吧。在我的經(jīng)驗中,如果實現(xiàn)業(yè)務邏輯所需要的java Object超過3個的時候,認為用POJO(通常有一個接口)方案更復雜的人很少:給我印象深刻的是,那些否定POJO方案的那些人,真正嘗試兩種方案并做出對比的人為零??赡芩麄冇凶约旱挠^點,但我并不知道。(也許直接的事務和遠程方法更另人愉悅?)我真的非常希望看到能真正證明基于POJO的方案更復雜更難用的評論。
Rod:為什么Spring比EJB簡單易用?我不能給你一個獨立的主觀臆斷,我可以告訴你的是,我是借鑒EJB,并運用我多年的經(jīng)驗來設計Spring的,我也很樂于去比較.從一開始,Spring(或者其他的IOC加Services框架)框架就是和你的業(yè)務代碼隔離的,沒有藕合的.這個區(qū)別是很有重大意義的。任何Object可以被事務化而不需要陷入EJB的叢林中。這對于代碼的重用也是有意義的。實際上,在你自己的業(yè)務對象中,很少有框架的侵入,換句話說,你會有更多的自由去運用面向對象的分析設計。
Ted:哦,我已經(jīng)說過了,企業(yè)級系統(tǒng)通常不是來練習OO(面向對象),因為那么做有一種讓我們陷入麻煩的危險趨勢----這也就是為什么人們在網(wǎng)絡計算的趨勢下,使用CORBA,DCOM和RMI來解決問題的原因。你應該考慮一下,把collection置于服務器端,iterator放在客戶端的意義,然后你就明白.....
Rod:Ted,我提到的"更多自由去使用OO",并不是說所有地方都用OO,當然,分布式對象是很需要的。但重要的是,不要把"企業(yè)應用"和"分布式應用"混為一談. 應用程序的內(nèi)部結構應該盡可能的面向對象.然后提供一個高層的接口對遠程調(diào)用暴露,理想狀態(tài)下,僅僅這個接口才可以放棄面向對象.(基本上像SDO--服務數(shù)據(jù)對象Service Data Objects這樣的解決方案在這部分是很龐大的).所以在分布式對象建模中,在應用內(nèi)部引入優(yōu)秀的應用程序接口(雖然破壞OO)是沒有爭議的。Spring和其他的IOC(inverse of control控制反轉)容器,不會在OO方面設置障礙,而EJB就沒做到,它大范圍內(nèi)地依賴了EJB的接口和框架。
在我對于Spring的XML配置要比EJB復雜的部署描述文件簡單易配置的評論后----Ted寫到:公正地說,Rod--JSR 175 在簡化部署描述配置(包括你的Spring的XML配置)方面的所做的工作是有意義的(而不是所有),在java5之前,部署描述文件是一個必須的,很惱人的事情嗎?不幸的是,事實表明,考慮到所有的可能性,這已經(jīng)是最佳的解決方案了。(所有人都記得EJB1.0時,基于對象的描述符)。
Rod:沒錯,JSR-175會在DD(Data Define數(shù)據(jù)定義)方面進一步改善(已經(jīng)有所改善,雖然注釋被一再過度使用,不過那是另一個話題了).不錯,DDs(數(shù)據(jù)定義文件)是必要的,雖然很繁瑣,這是java借用C#中屬性集/注釋的想法而來的.但問題是,現(xiàn)在的EJB部署描述讓人驚駭?shù)厝唛L,差不多全在XML里.而且一個標準的ejb-jar.xml部署描述文件并不夠,通常需要兩個。相反,Spring的配置文件短小精悍,而且不需要額外的引用。當然,EJB3.0不在這里討論,因為我想評論的是現(xiàn)在使用EJB的方案(直到2006或者JSR-220完成的時候)。
??? 在Don的博客上,我對他拿Spring進行的測試表達了我的尊敬:
?? Rod:因為你的代碼不是嚴重依賴于容器的,所以可以方便的進行單元測試,比如用JUnit。這樣一來,和過去傳統(tǒng)的J2EE容器內(nèi)測試方案比起來,提高了巨大的效率。你也可以在Spring容器上做集成測試,而不需要一個重量級的J2EE應用服務器----不像其他應用服務器,Spring容器可以很快啟動。
Don:我僅僅是說盡量少的依賴于容器,EJB并不是一個完全失敗的技術,用OpenEJB容器效率并不會很低的,至少從我的測試來證明。
Rod:我并不確定像OpenEJB這種輕量級的EJB容器會是一個另人滿意的解決方案.我沒有遇到有人用過它,我自己也沒用過。真正的EJB測試總是繁雜的,通常需要五分鐘一個編碼/測試循環(huán)。
Rod:比較一下Spring的Pet Store例子和EJB方案的,就可以發(fā)現(xiàn),在Spring的例子中,很少有冗余的代碼,也就是說什么都不做的代碼...
比如Service接口,JNDI服務查詢操作等等.在我接觸的項目中,用一個Spring+Hibernate的混合框架,至少能拿去EJB方案的10%---20%的代碼,對于項目的提交和后期維護是有重大意義的.
Don:我來說說我的觀點,簡單并不永遠是好的,不幸的是,它僅僅代表簡單,沒有JNDI,就等于說犧牲了管理人員在不重啟服務器的情況下,對配置進行調(diào)整的需要。這可能對于一些客戶的應用來說不是太重要,但對于一個24*7的應用來講就是個大問題了。
Rod:當然,我說的用Spring終結你代碼中的"服務接口,JNDI查找",并不是說真的不用JNDI,比如說,你還是希望調(diào)用EJB,Spring可以給你創(chuàng)建一個代理,封裝了JNDI查找啊。
在Pet Store的例子中,我盡力尋求一個簡單的架構--既然我們來討論Pet Store,關鍵的就是,Spring和其他輕量級的框架技術,給了你一個簡易框架的選擇。如果是傳統(tǒng)的J2EE,你想創(chuàng)建一個Pet Store,你最好是用Perl或者.Net,或者拋棄J2EE的高級特性,只選擇Servlet和JSP,所以有一個你自己的簡易架構是必要的。
沒有JNDI,就等于說犧牲了管理人員在不重啟服務器的情況下,對配置進行調(diào)整的需要",嗯,有多少需要用JNDI重新配置應用的需要?更好的解決方案是JMX,但應用服務器并不了解你想做什么有意義的配置,同時Spring 1.2已經(jīng)加入了對JMX的支持,這將方便開發(fā)者去操作應用對象和配置。比如說,改變一個JNDI的環(huán)境變量是我們很少要做的事情.開發(fā)者通常會很準確地配置這些信息,來避免修改的痛苦。(我同意,這可能是個不好的假設,但確實通常是這樣的),你如果想通過JNDI來改變某個值,你已經(jīng)知道何時來找到它,等等。
Don:請記住,EJB提供雙機事務的支持,而Spring沒有,這一點讓我不安,Spring失去了它的亮點。
Rod:Spring不會做或者很少做雙機事務,不知道怎么就確定Spring失去它的亮點了,Spring的事務層抽象是在事物策略的基礎上的一層,一個方案就是JTA,在這種方案下,雙機事務來自于應用服務器底層的支持,而不是Spring.實際上,JTA事物策略是我們最早就重視并實現(xiàn)的功能。我明白,在一個無JTA支持的簡單容器下,丟棄一個落后的local和global事務編程模型是很有意義的.