轉貼:Spring vs. EJB
引自:http://www.cnblogs.com/raimundo/archive/2004/09/20/44697.html
我知道我要挨扳磚,沒事,來吧:)
赫赫,我來說一下spring vs EJB,首先強調,我不是ejb的擁護者,但我欣賞他的完整、他的學院氣,同時也深感他的硬傷,我不是spring的擁護者,雖然去年3、4月間看
到spring的時候曾經讓我眼前一亮。對ejb有太多的誤解,對spring有太多的吹捧,我希望這是一個相對公平的比較.
我認為spring和ejb的差異在這樣三個方面,一個是受眾也就是這兩個叫framework也好叫platform也好的東西的scope;另一個是component architecture,最後一個是語義
。
1.Scope比較
先說scope,ejb的scope是什麼?ejb針對什麼系統來設計的?這個我想一個人一個答案,我說了不算,同樣大家說了也不算,我們來看規範(題外說一句,我想本來我沒啥
資格在這裡談論ejb,我應用ejb的專案不多,但是我有個習慣,就是讀規範學技術,不管別人怎麼說先看這個東西是怎麼來的,我想這一點還使我有些開口的自信,不至於太
貽笑大方),ejb規範的頭幾句:
Enterprise JavaBeans is an architecture for component-based computing.Enterprise beans are components of transaction-oriented enterprise
applications.
好了,很明確,ejb是針對transaction-oriented enterprise application的元件,那麼也就使說ejb是面向以事務為中心的企業軟體,而不是別的。ejb的核心是
transaction,不是domain model或別的。
why transaction?我在電力行業做過一陣資訊化軟體架構師,在電力這樣一個需要處理大量資料的領域裡,很少有oo model,而是做完entity分析,交給dba去優化,以資料
效能為主,這樣的系統裡,資料操作的粒度就是transaction,而不是object或是別的。我想這該算是一個大型企業級系統,我看到的是transaction,因此ejb這個把scope定
在enterprise級的東西而言,這樣的設計還使合理。而且ejb對transaction這部分的處理確實比較完整,cmt,bmt,不同的transaction scope控制的都很好。基於這種認識,
我認識transaction script是ejb的標準應用模式,而不是domain model或是別的。
這是對ejb最大的誤解的來源,我看過的所有ejb書裡,只有o'reilly的一本隱約提到transaction是ejb的中心。其他一律不提,瘋狂的鼓吹ejb多好多好ejb多麼萬能,我想
,如果不知道ejb是transaction-oriented的,那麼ejb奇怪的物件模型的確不可接受。
再說spring,spring是什麼呢?我沒有看到特別明確的定義,不過我想仿照ejb,定義spring為:
Spring is a Javabean-based framework that supporting component architecture development.Spring provides lighter context for heterogeneous entrprise
application.
我e文很差,cet-6 6次都沒過,我想說明的是,spring是一個輕量化的元件架構,可以支援多種企業應用程式模式.看到這裡有人又該說了,no,no還有ioc,還有aop,沒錯這
些很cool的特性我沒說,但是包含了,component architecture意味著兩個方面,component working(編寫元件)和container working(編寫容器環境),spring的ioc和aop是
用在container working裡的.當然肯定還有其他的一些沒有概括,但是我想主體我還是說到了的.這樣scope就很明確了,spring的基礎是javaBean,javaBean支援完整的oo建
模,因此spring可以適用更多的結構,domain model和別的一些。
那麼開始比較,spring有一個理論上普適的元件模型,但是鑑於大型應用多為transaction-oriented,那麼用spring的理由就是domain model,ejb不能提供完整的oo模型而
spring可以。
結論:由於scope不同,其實比較spring和ejb那個更適合企業開發沒什麼意義,因為這裡面根本就是兩個不同的範疇,在scope上指責ejb不如spring,就好像說raimundox,你
就不能替老婆把孩子生了,還讓她那麼痛苦的懷胎十月。其實我也不想,我也想替,可惜我們這功能.....扯遠了,ejb也是,沒這功能你怎麼強求他呢?你要說ejb設計的不好
,也不對,人家有專門的領域。因此我說,在scope上比較spring和ejb沒意義,根本不是一個級別的。
2.component architecture
Component architecture有一個基本觀點,就是component和context的分離,理想情況下,component只負責業務的實現,而container提供context,這個context只技術
context,比如事務比如安全的支援。於是,component architecture的基本觀點就是business關注點和technique關注點分離,business由component負責,technique由
context或者叫container實現。那麼很明確了,component architecture裡有兩種程式設計,針對component的和針對container的。
好,有了這個理解,我們可以繼續了,如果有人有疑意,那麼抱歉,這片文章並不適合您,後面全部的論點都是基於這個觀點的,如果不認可這個,下面的也不會認可,您
也不用浪費時間了。
首先看ejb的component方面,ejb在component architecute做得非常的好,ejb就是一個業務元件,在container-managed的情況下,元件通過宣告可以應用容器提供的技術
context,當container-managed不滿需要的情況下,可以bean-managed,只要保持對外的事務語義就可以了(記得嗎?ejb是transaction-oriented,事務最重要)。在ejb裡
,元件和容器的約定非常明確,哪些需要元件寫,哪些是容器提供的非常明確,這是component architecture裡很好的習慣,明確元件和容器的界限(ejb的一個缺點,矯枉過
正,有一些操作也被禁止)。編寫程式碼非常容易,業務,only業務。其實ejb的規範裡,ejb的coder其實最好是domain expert,實現業務邏輯就好了。
現在來看spring的component方面,spring以javaBean為基礎,貧容器,也就是對容器沒要求,於是,spring第一個缺點,contianer和component的約定不清晰(寫到這裡我
已經聽到一些人在叫了,這是spring的優點,自由,別急,後面我會證明這是spring的軟肋),但是spring用了一種比較聰明的辦法,那就是加強container working.
看一下spring的container working,通過spring的aop api,我們可以很容易的為特定元件定製容器環境,把一個元件需要的容器技術環境以aspect的形式weave到component
裡,非常的靈活,也非常的強大,spring通過這種形式來彌補元件/容器約定不足的情況,一切由component選擇,容器除了裝配(ioc/dip)不提供任何技術context,想要什
麼自己來,這個給了component實現者自己選擇的權利,很好(但也隱含了spring的最大的不足,別急我後面會說)。
再來看ejb,非常遺憾,ejb container working的能力幾乎為0,當然算上jca的話還不算太差,但是那只是資源,而不是技術context。why?因為ejb認為他已經提供了所有
企業級開發所必需的技術context了,事務(ejb裡我總把他放在第一位)、分佈、併發、安全等等。在ejb看來container working的能力幾乎無用,而且不安全,除了jboss開放
了比較多的container working介面其他的ejb container提供這方面的支援很少很少.當然提供很多技術context並不是壞事,要命的是不能配置,要麼全用要麼不用(倒是很
原子),這是ejb最大的不足,容器環境不可配,也是spring強於ejb的地方。
上面我們已經看到了spring和ejb都是component architecture,那麼component能想到的最直接的用處就是複用。那麼比較這一點就是比較ejb和spring component
architecture的關鍵。看到這裡spring的支持者們該常出一口氣了,spring複用一定強於ejb複用,赫赫,但我的結論正好相反,ejb複用優於spring複用!!收起你們的憤怒
,收起你們不屑,聽我把話說完。
在component architecture裡,component是業務實現,而不該有技術程式碼,就算用也要通過容器環境去和容器互動來完成操作,比如ServletContext等東西。那麼其實
組建結構下複用的關鍵不是組建而是容器!!
以前有一個頗有名氣的dx(gigix別看了,說你呢),說"COM和EJB都鼓吹模組化和複用,模組化是真的,複用是騙人的",com我不是很熟,不好下結論,ejb呢?ejb不易複用我
承認,但是騙人嗎?不騙,後面我給出一種ejb複用的思路大家參考。反正元件一點技術都不作,只有業務邏輯想用就要有相應的容器環境,那麼容器環境的複用性才是元件復
用的關鍵。ejb不易複用是因為如果脫離容器,我們就必須給它提供相應的技術context,事務、分佈、併發等等一個也不能少,因此容器外複用ejb效率很低。注意,
是容器外,元件本來就是跑在容器裡的,誰讓你非要拿出去用),而容器內呢?因為ejb規範規定ejb容器應該相容,別說webSphere到bea的移植有多難,其實不難,或
者說難度比把spring元件移植到pico複雜一點,當然你用vendor-specified的特性就沒辦法了,這不再規範內,你違規就別怨人家。因此,ejb的複用是可以的,而且是規範保
證的,容器外也有辦法,也不是很難,我後面說。
再看spring,的確他很靈活,但這正是致命傷,component完全是業務實現,但是容器呢?spring怎麼保證容器的環境?沒有,只能你自己保證,當你沾沾自喜的說,spring
裡的component都是pojo,可以很好複用的時候,可曾想到,這複用的代價是要複用容器。比如有個componentA,在SystemA裡需要事務模型A和安全模型A,在SystemB裡需要事
務模型B和安全模型B,當你從SystemA裡複用componentA的時候,你要怎樣?重寫事務模型B和安全模型B,然後你可以堂而皇之的說,你複用了元件。的確,你複用了元件,但
是你重寫了容器,值嗎?更可怕的是,spring容器和元件沒有約定,那麼怎麼保證你的組建不寫技術程式碼?ejb只要Bean-Managed並提供統一的事務模型就好了,spring呢?你
靠什麼保證?你自己?這是spring一大硬傷,完全container-managed下缺少特定的component邊界控制.你可以說,特殊要求的事務模型ejb還實現不了呢,的確,這是有可能
,但是ejb transaction model不能適用的情況有多少?如果真的不行,只能說ejb的簡單複用在這裡失效。
對於元件還有一個問題就是部署,這也是ejb為人詬病的地方.的確,ejb的部署夠複雜,但在ejb規範裡有一個專門的角色來負責部署的,ejb是component architecture,那
麼比如有一個人來粘合技術和業務,這個人不該是programmer(我剛才說了,ejb的實現者最好是業務專家,實現業務邏輯),ejb的部署才是很厲害的人,他需要知道什麼業務
需要什麼樣的技術支援,該怎樣得到效能,因此deployer才是ejb architecture裡最牛的,我重來不以為寫ejb的是高手,但是一直都敬仰ejb的deployer.當然這裡有一個除錯
困難的問題,這是ejb的硬傷,沒辦法,這甚至是元件開發的硬傷.
再來看spring,spring宣稱他部署簡單,我覺得rod johnson在轉移視線,想想看,打成一個war和打成一個ear有多大的區別?那麼部署的差異在哪?差異在ejb的deploy
description和spring的context.xml的編寫上!在用spring開發中要有一個人來寫context.xml這個人往往比較瞭解系統,知道什麼元件用什麼攔截,那個元件依賴那個,甚至
會是架構師在作這件事情,那麼和ejb裡對系統有大局觀的人來做deploy有多大區別?可能就是Xml的編寫吧,我想在工具的支援下就是熟練度的問題,因此我覺得部署上
spring和ejb差不多,spring不用啟server,除錯放便些。
結論,在component architecture上,spring靈活,ejb統一完整,各勝擅長,spring的靈活以降低複用為代價,但是如果有common的技術實現,的確很好複用,但是
spring+一套common的技術實現也就約等於ejb了吧?
3.語義
那麼spring複用的問題表明了什麼呢?其實是缺乏語義的支援,ejb開發可以看作在一個統一的語義環境下來作的,這個語義由ejb規範規定,因此ejb的複用有語義保證,而
spring呢?貧語義,一切都要開發者自己來實現。因此,如果ejb的環境語義可擴充套件並且可配置(比如去掉分佈),那麼spring毫無優勢,標準的一致的完整的元件架構使ejb
會大有作為,但是現在並沒有,才有了spring的火爆.這是一種畸形的勝利,完備語義的輸給了貧語義的,問題是什麼,強迫消費...誰讓ejb非得強迫客戶去買用不到的分散式
環境的單?但是統一語義的威力不會因此掩滅,現在有兩條路,spring聯合os社群,制定lightweight j2ee語義集合,爭取成為標準。第二,ejb實現技術語義可配置可擴充套件。
誰會勝利?不好說,但是似乎ejb的腳步快一些!
附:容器外複用ejb
其實ejb在容器外完全是可以用的,但是為了最大限度保證能用,bean-managed是推薦(不是cmp,bmp而是cmt,bmt),那麼怎麼傳送一個transaction進去?SessionContext(
好像是這名記不清了,都快2:00了,困呀...就是ejb那個context介面),一個介面嘛,自己mock一下,給一個transaction進去就好了。怎麼裝配?spring的setter
injection。如果用spring,那麼cmt也可以實現,攔截啦,不過就看能不能實現ejb transaction model了。entity bean,如果是bmp,就用它好了,cmp,繼承一個上
hibernate。這些都模擬好了,找一個in memory的jndi,把spring context封進去,這樣相當於我們用spring實現了一個lightweight ejb container(其實就是給spring一個
ejb api的皮),輕到什麼程度?除了注射什麼都沒有。
然後client就可以構造jndi,然後lookup了
看到這裡一定有人說,你吃飽了撐的,這麼費勁容器外複用ejb,為什麼不直接用spring,這樣也不夠pojo,每個元件都有ejb的類的繼承,好,我告訴你這麼做的好處,首先
,雖然不夠pojo,但是足夠bean,因此spring來管理ejb是可以的,證明我的觀點容器外使用ejb可以(赫赫,不要說偶rpwt...).其次的,當業務發展了,你的系統需要分佈了
,把spring去掉,拿出ejb,redeploy,ok了,延展,穩定,分佈都有了,這才是複用該有的境界,改一個部署整個環境換掉,去掉lightweight的ejb container,換乘
heavyweight的就是重量級。
當然這麼實現很難,在ejb3裡會容易些,我敢打賭,spring以後一定是lightweight ejb container的供應商,免不免費,os不os要看rod johnson了,不過我覺得希望不大。
致謝:
首先感謝dlee,在和他的討論中形成了這篇文章的主題,然後是冰雲,他幫我審稿直到2:04,udoo,perhaps都提出了中肯的意見,謝謝他們.
當然也歡迎大家訪問我的blog:www.cnblogs.com/raimundo
相關文章
- Spring WebClient vs. RestTemplateSpringWebclientREST
- EJB系列教程 (轉)
- Comparison of Spring and EJB3Spring
- 翻譯:EJB in a Nutshell (轉)
- Airflow vs. Luigi vs. Argo vs. MLFlow vs. KubeFlowAIUIGo
- Oracle for Linux vs. Oracle for NT(轉)OracleLinux
- Spring 和EJB終於統一融合Spring
- spring,ioc模式與ejb3呼叫Spring模式
- EJB設計模式5 (轉)設計模式
- EJB 程式設計模型 (轉)程式設計模型
- EJB設計模式2 (轉)設計模式
- EJB設計模式3 (轉)設計模式
- EJB設計模式4 (轉)設計模式
- EJB設計模式1 (轉)設計模式
- EJB設計模式(第二版)之EJB Command (轉)設計模式
- MVC vs. MVP vs. MVVMMVCMVPMVVM
- Laravel vs. Spring Boot:後端開發選擇LaravelSpring Boot後端
- ORACLE lock 轉貼Oracle
- 轉貼crontab 命令
- JBoss中EJB的開發(轉)
- J2EE vs. NET, Java vs. C#:比較公正的評價 (轉)JavaC#
- java bean 與 ejb的區別 (轉)JavaBean
- 轉貼_字串分隔_拆分字串
- [轉貼]Skip Scan IndexIndex
- 核心管理概述(轉貼)
- 轉貼_roger大師_
- git revert .vs. git reset .vs. git rebaseGit
- String.format VS. StrSubstitutor VS. NamedParameterJdbcTemplateORMJDBC
- 【演算法】轉載:Iterative vs. Recursive Approaches演算法APP
- 搞懂:資料科學vs.機器學習vs.資料分析vs.商業分析資料科學機器學習
- EJB設計模式之Data Transfer Object (轉)設計模式Object
- mysql 命令集(轉貼)MySql
- c# web service轉貼C#Web
- 農行的VIP (轉貼)
- ejb服務能否轉換成socket服務?
- 學習EJB CMP/CMR 的心得體會 (轉)
- EJB菜鳥入門三板斧:) (轉)
- 運用反射實現ejb動態委派 (轉)反射