日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

EJB(2.X-3.0)、Hibernate、Spring:剖析、批判和展望

 figol 2006-03-11
 

EJB(2.X-3.0)、Hibernate、Spring剖析、批判和展望
 
                                                         TomHornson#(at)#hotmai.com

 

 

                                                         12/28/2004于珞珈山

 

 


 

 

 


 
一段時間以來,EJB、Hibernate、Spring的恩怨情仇,是J2EE的熱門話題。EJB VS HibernateEJB VS Spring

樣的議題隨處可在。這篇文章,筆者試圖通過對技術(shù)發(fā)展史的回顧,對
source
的剖析、對比,深入挖掘這些技術(shù)出現(xiàn)的初衷、缺陷、走向。

 

 

一、    前言

 

 

  我強(qiáng)調(diào)EJB、HibernateSpring的恩怨情仇,同時也必須說明,我一向反感你說我怎么侵入、你說我怎么依賴式的EJB VS Hibernate、EJB VS Spring的討論,因為這種行為本身就是沒有意義的、錯誤的。我提倡從正確的技術(shù)對比和理性的技術(shù)批判中受益。對比,我們需要找準(zhǔn)對比點;批判,我們需要從source、specapplication context中分析、批判。

 

 

 

 

 

二、    EJB說起

 

 

2.1 EJB幾種Bean類型的引入順序

 

 

  EJB1.0,有兩種Bean類型:SessionBean、EntityBean

 

 

  EJB2.0,引入CMP EntityBean、引入Message-Driven Bean、引入Local接口。

 

 

 

 

 

2.2 Entity BeanO/R Mapping的微妙關(guān)系

 

 

  我想對O/R MappingO/R Mapping Engine做一個簡要的說明。

 

 

  O/R Mapping,以對象視圖(Object View)來看待DB Record,對象操作能夠通明地映射成DB Record操作。

 

 

  O/R Mapping Engine,就是使得O/R Mapping成為可能的具體實現(xiàn)手法。

 

 

從我們的定義來看,使用BMP EntityBean意味著你自己在實施一個非常簡單的O/R Mapping ,你自己在為能夠以對象視圖和DB交互做出努力。而為了支持CMP EntityBeanEJB Server提供商會為你提供O/R Mapping 能力。而且,事實的確是這樣,任何支持CMP EntityBeanEJB Server都需要提供一個Persistence(O/R Mapping) Engine,譬如JBOSSJAWS(Just Another Web Store)。

 

 

  至于,Hibernate、IBATIS等,雖然,也叫做O/R Mapping Tool,但是它們的意義已經(jīng)遠(yuǎn)遠(yuǎn)超過了CMP EntityBean O/R Mapping Engine這樣的Tool。下面會有詳細(xì)的分析。

 

 

 

 

 

2.3 EJB-1.0

 

 

  EJB1.0是分布式組件架構(gòu),包括SessionBeanEntityBean。它引入了很多非常前衛(wèi)的技術(shù)、概念。主要包括分布式組件、容器、DB操作的對象試圖。

 

 

  EJB1.0,可能Expert Group設(shè)想的EJB的應(yīng)用場景是大規(guī)模分布式的系統(tǒng)。所以,SessionBean、EntityBean尚沒有引入Local接口。 client->SessionBeanclient->EntityBean、SessionBean->SessionBean、SessionBean->EntityBean等等都是remote的。

 

 

  EJB1.0,將容器這個概念引入EJB,意義重大。這里我想順便澄清一個問題:容器是什么?我的觀點:容器只是一個概念、一種架構(gòu)。就拿EJB Server來說,Server試圖為Bean提供分布式、事務(wù)、安全等基礎(chǔ)設(shè)施,那么就必須有一個凌駕于Bean之上的Layer或者說warp,這樣才能夠從高層攔截Bean調(diào)用,進(jìn)行一些額外操作。這樣的架構(gòu)就叫做容器架構(gòu),這個概念當(dāng)然不是自EJB才有的。至于怎樣實現(xiàn),方法各異。

 

 

 

 

 

事實上,以個人的觀點,容器架構(gòu)的核心,不在于從高層“掌握”Beans(Objects),而在于采用怎樣的技術(shù)來實現(xiàn)Bean(Object)調(diào)用的攔截。無疑,EJB ServersSpring的實現(xiàn)手法是不同的。下面會詳細(xì)討論這個問題。

 

 

 

 

 

  EJB1.0DB操作提供了對象試圖。Expert Group當(dāng)初是怎樣定位EntityBean的?無疑,1.0中的EntityBean,也就是2.0以后的BMP EntityBean,定位是Domain Object(我不知道當(dāng)時有沒有這個概念,只是它們的思想是非常一致)。它的fields直接映射DB Table Schema,member functions就是對Table Record的操作。Client->EntityBean、SessionBean->EntityBean等就可以直接和數(shù)據(jù)庫交互了。

 

 

  有人跟我說EJB1.0基于Catalysis方法學(xué),SessionBean對應(yīng)RoleEntityBean對應(yīng)Domain Object。到目前為止,我對這種說法,持保留態(tài)度,因為EJB Spec中,我絲毫沒有這種說法的痕跡。

 

 

 

 

 

2.4 EJB-2.X

 

 

  無疑,EJB1.X的設(shè)計存在重大的缺陷。2.0增加的特性包括Local接口、CMP EntityBean,它們是對1.x缺陷的重大更正。

 

 

  首先,事實上沒有多少Expert Group想象中的大規(guī)模分布式應(yīng)用。我們從兩個方面來說:(1)通過Remote方式使用 EntityBean引起嚴(yán)重的性能問題,很有必要提供Local接口。(2)訪問SessionBeanWebApplicationSessionBean部署在同一服務(wù)器上的情況非常普遍,所以提供SessionBeanLocal接口,也是必然的事情。2.X之后,最常用的一個Pattern就是使用SessionBean Façade通過Local的形式訪問EntityBean。而且,即使應(yīng)用規(guī)模大到連SessionBeanEntityBean都需要部署到不同的Server,也沒有關(guān)系,因為EJB2.X同樣支持Remote接口。

 

 

  其次,EJB2.0引入CMP EntityBeanCMP EntityBean解決了EntityBean持久化表示和JDBC分離的問題,同時大大簡化了EntityBean的開發(fā)、提高了性能。但是,我不得不說,CMP EntityBeanEJB1.XDomain Model理念完全沖掉了,因為CMP EntityBean是不能包含任何Domain Logic的。BMP EntityBean似乎就是Matrin所說的DomainObject,而CMP EntityBean在典型的SessionBean->EntityBean這樣的應(yīng)用場景下,似乎就是Martin所說的Transaction  Script中的AnaemicDomainObject

 

 

順便說一下,我個人是不同意MartinRichDomainObject的說法。因為,在數(shù)據(jù)應(yīng)用系統(tǒng)中,Martin提到的相對于Transacton ScriptAnaemicDomainObjectRichDomainModel往往沒有反映現(xiàn)實世界。一個Bank Account反映到現(xiàn)實世界,就是賬本中的一條記錄,它沒有自發(fā)的動作,譬如withdraw。它和Person不同,Person可以有say(String words)這樣的自發(fā)動作。Accountwithdraw應(yīng)該放到AccountManager中,由AccountManger來操作Account。不是說OO中的Object都需要有動作,現(xiàn)實世界中,本來就有靜態(tài)的、沒有自發(fā)動作的事物,譬如一個賬本、一個賬號、一個資料庫。雖然,不可否認(rèn),Rich Domain Model(對比AnaemicDomainObject說的)能夠帶來不少的好處(什么樣的好處,你看看MartinDomain Logic and SQL,就知道了)。

 

 

 

 

 

三、    我理解的Hibernate

 

 

  本來,本文的題目叫做《EJB、Spring:剖析、批判和展望》,因為我覺的HibernateEJB、Spring不是一個層次的東西,雖然,這個道理很淺顯,但是為什么那么多人還拿Hibernate來攻擊EJB,來攻擊EntityBeanEntityBean是值得狠狠攻擊的,但是你用錯了槍。

 

 

  我上面提到,支持CMP EntityBeanEJB Implements都有一個Persistence Engine,也就是O/R Mapping EngineCMP O/R Mapping Engine用來做什么的?它通過分析CMP Abastract Schema、分析EJBQL、分析Bean狀態(tài)等行為,生成SQL,然后和DB 進(jìn)行交互。

 

 

而在我眼里,Hibernate不是”O/R Mapping Tool”這幾個字能概括的了。我說Hibernate是一款獨當(dāng)一面的輕量級翻譯中間件,是Layer,和CMP EntityBean O/R Mapping Engine不是一個層次的東西了。

 

 

Application------->CMP EntityBean Operation-------->DB

                              |
              
  (O/R Mapping Engine)

 


 

 

 

                                           |---HQLCriteria Query

 

 

Application------> Hibernate ------> |---POJO/PO Operation---------> DB

 

 

                                           |---and so on

 

 

  通過上面的兩個圖,你看出區(qū)別來了嗎?

 

 

  EntityBean應(yīng)用,不知道O/R Mapping Engine的存在,只需要使用EntityBean來完成交互。

 

 

  而在Hibernate應(yīng)用中,Application是直接使用Hibernate的。也就是說,它是直接使用O/R Mapping Engine的。

 

 

  在這里,我建議你停下來,想想EntityBean是不是應(yīng)該對應(yīng)Hibernate中的PO/POJO?舉個例子,你修改PO后,有時是不是需要sessionObj.update(po)來更新(當(dāng)然,在非夸Session的情況下,不需要顯式的update的),這個sessionObj.update(po)是不是表示你直接使用HibernatePersitence Engine?是的。而在EntityBean中,你修改EntityBean后,你需要其它的行為來使得EntityBean的變化同步到DB嗎?不需要。因為,EJB Container攔截你的調(diào)用,在你更改Beanfield之前、之后,container會調(diào)用load/store方法的(當(dāng)然,在BMP/CMP EntityBean中,情況是不同的,BMP EntityBean調(diào)用programmer自己用JDBC編寫的load/store等方法,而CMP EntityBean,使用CMP Peristence Engine來做這個工作)。這樣,就隱式的持久化數(shù)據(jù)了。不需要,你像Hibernate那樣調(diào)用session.update這樣的語句。EntityBean這種同步方式是對它性能差的重要原因之一。值得注意的是,EJB Implements對于EntityBean同步并不完全是我上面描述的那樣,同步的頻率和事務(wù)、特定的implements是緊密相關(guān)的。

 

 

  總的來說,CMP EntityBean O/R Mapping Engine是為靜態(tài)的、功能固定的EntityBeanO/R Mapping提供支持而開發(fā)的。而Hibernate擔(dān)任的是一個Layer的作用。

 

 

 

 

 

四、    Spring不是神話

 

 

  Rd Johnson聰明在哪里?聰明在,他堅持了自己的實踐,而不是隨大流。Rd Johnson認(rèn)識到90%的應(yīng)用不需要分布式、不需要J2EE中那些重量級的技術(shù),譬如JNDI,他就動手為EJB脫去Remote這層皮、將大多數(shù)應(yīng)用中不必要的技術(shù)隔離、改造。從適用范圍上來說,SpringEJB做了90%的補(bǔ)充。

 

 

  個人看法:Spring的哲學(xué)在于,framework針對最常見、最簡單的應(yīng)用場景而設(shè)計,等到需要特殊技術(shù)的時候,再想辦法解決問題。這樣,在絕大多數(shù)沒有特殊要求的應(yīng)用中,Spring就顯示出優(yōu)勢來了。下面,我們會做詳細(xì)的講解。

 

 

 

 

 

4.1 Spring“無侵入性“是謊言,但是有資格笑”百步之外的EJB”

 

 

 “無侵入性”是Spring標(biāo)榜的特性。但是,我想說,Spring的“無侵入”是謊言,隨著應(yīng)用的深入,“無侵入”對什么framework來說,都是個神化。

 

 

  什么就叫“無侵入性”?部署到Spring中的Object不需要強(qiáng)制任何實現(xiàn)接口就可以說Spring是“無侵入性”的?我覺的,這是大錯特錯。如果你非要說,Spring的確不需要像EJB那樣強(qiáng)制實現(xiàn)一些接口,那么我只能告訴你:

 

 

(1)Spring設(shè)想的Object的應(yīng)用場景是從最簡單的出發(fā)。所以,它沒有,為了一些預(yù)料中要使用的特性而強(qiáng)制Object實現(xiàn)一些特定的接口。但是,事實上,在Spring中,如果你的應(yīng)用場景稍微深入一點,那么你就和和Spring綁定了。

 

 

(2)Spring管理的Object,從某種意義上說是沒有狀態(tài)的。

 

 

針對第一點,我舉兩個個例子。(1)EJB內(nèi)部方法的調(diào)用,會導(dǎo)致基礎(chǔ)設(shè)施不會起作用。但是Bean接口(SessionBean、EntityBean、MessageDrivenBean)中都有可以使Bean獲得自己Context的支持,譬如:SessionBean的setSessionContext(SessionContext ctx) 等等,容器部署B(yǎng)ean的時候會通過它給每個Bean設(shè)置一個上下文。而EJBContext中,有EJBObject getEJBObject這樣的函數(shù),可以使得Bean獲得自身的EJBObject,這樣通過EJBObject來調(diào)用Bean自己的函數(shù),基礎(chǔ)設(shè)施就會起作用了。而Spring中,如果,一個Object的函數(shù)需要調(diào)用自己的其它函數(shù),而又希望譬如安全檢查、事務(wù)等等Aspect起作用?那么Spring,怎么做?你需要設(shè)置Bean的exposeProxy屬性。

ExposeProxy whether the current proxy should be exposed in a ThreadLocal so that it can be accessed by the target. (It‘s available via the MethodInvocation without the need for a ThreadLocal.) If a target needs to obtain the proxy and exposeProxy is true, the target can use the AopContext.currentProxy() method.

 

 

所以,當(dāng)你需要上面說的內(nèi)部調(diào)用需要基礎(chǔ)設(shè)施起作用的特性,不管在EJB還是Spring肯定需要和特定框架綁定的。為什么說,Spring五十步笑百步?因為,我上面提到,SpringObject很簡單的情況下,是可以任意部署的、復(fù)用的。而EJB卻不管你需不需要,開始就設(shè)想你需要的。同樣,Spring中的BeanFactoryAware、BeanNameAware等等接口也都說明了一點Spring將特性從Object剝離,從而,盡量降低它的依賴性。只有當(dāng)你的Object復(fù)雜的時候,framework才會侵入你的Object。

 

 

  針對,第二點,我想著重談一下。為什么說,從某種意義上說Spring中部署的對象是沒有狀態(tài)的?我們知道,Spring支持兩種ObjectSingletonPrototype。Spring Spec中,認(rèn)為,Singleton可以稱為stateless的,Prototype可以稱為是statefule的。而在EJB的世界中,StatefuleSessionBeanEntityBean也稱作是stateful的。那么,它們的stateful分別意味著什么?它們?yōu)槭裁丛谝蕾囆苑矫嬗心敲创蟮膮^(qū)別?為什么Spring中的Object不需要實現(xiàn)特定接口,而EJB需要?先來,看看EJBSessionBean接口:

void

 

 

ejbActivate()
          The activate method is called when the instance is activated from its 
          "passive" state.

 

 

 void

 

 

ejbPassivate()
          The passivate method is called before the instance enters the
          "passive" state.

 

 

 void

 

 

ejbRemove()
          A container invokes this method before it ends the life of the 
          session object.

 

 

 void

 

 

setSessionContext(SessionContext ctx)
          Set the associated session context.

 

 

其中的setSessionContext我上面說過。看ejbActivate()、ejbPassive(),為什么會有這兩個函數(shù)?而Spring不需要實現(xiàn)有同樣函數(shù)的接口?這是EJBSpring的對象管理機(jī)制的不同造成。EJB implements一般來說,為了復(fù)用Bean,會采用一級Cache加上一級InstancePool(StatelessSessionBean是不需要Cache),從而支持將StatefulSessionBean持久化到磁盤,支持EntityBeanBean Instance(注意這個Bean Instanceclient得到的EntityBean是不同的,它沒有和任何的DB Record關(guān)聯(lián))的復(fù)用,這就導(dǎo)致了ejbAcrivateejbPassivate等的引入。但是,Spring沒有采用這樣管理機(jī)制,它只有Singleton/Prototype。而Prototype雖然也可以說成是Statefule的,但是它不會在不同的client中復(fù)用Object Instance,而是每一個client一個對象,哪怕一萬個client,那么就產(chǎn)生一萬個Instance,而在EJB中,可能使用100 Instance來服務(wù),將not activeBean持久化到磁盤,復(fù)用Bean Instance。還請注意,這里我不是說EJB中的StatefuleSessionBean好,事實上我發(fā)現(xiàn),一般來說,當(dāng)并發(fā)量很大時,采用節(jié)約內(nèi)存而持久化Bean到磁盤這種策略,I/O瓶頸引起的問題更為嚴(yán)重。

 

 

  再看,ejbRemove,這個沒什么多說的,Spring中你可以選擇實現(xiàn)InitializingBean、DisposableBean接口,但是Spring推薦不要這樣做可以寫普通的init成員函數(shù),然后在配置文件中指明init-methoddestroy-method屬性,這樣避免和Spring框架的綁定。

 

 

  總的來說,Spring從對象最基本的引用場景出發(fā),當(dāng)需要復(fù)雜特性的時候,才會采用特殊機(jī)制來解決問題,也就是在這時,才會使應(yīng)用綁定到Spring中。所以,它的侵入性比較低,但是不是“無侵入性”,不是你想的那么美好,當(dāng)然,也沒有“絕對無侵入“的framework。

 

 

 

 

 

4.2 我覺的Spring IOC的設(shè)計思路不夠完美

 

 

  SpringIOC被一些人當(dāng)作多么神奇的東西。

 

 

EJB具有Spring中所說的那種IOC的能力嗎?答案是肯定的。EJB中的EJB引用、資源引用、環(huán)境屬性都可以說是IOC,不是嗎?然而,SpringEJBIOC不同在哪里?

 

 

Spring注入的特色:主要考慮Local Object的查找這個時候不需要任何的協(xié)議譬如JNDI),當(dāng)你需要注入Remote Object的時候,采用RMI協(xié)議或者使用第三方Tool(譬如Hessian。

 

 

EJB的特色:無論你的Bean-Bean是否部署在同一臺機(jī)器上、Client->Bean是否在同一臺機(jī)器上,肯定需要通過JNDI來查詢Bean,只是,如果是它們在同一臺機(jī)器上的時候,你使用Local接口,這樣使得調(diào)用變?yōu)?/span>Local調(diào)用,從而提升性能。EJB它從出生時起,就定位為分布式組件架構(gòu),一頭栽進(jìn)distributed”不容易出來了。這個可能就叫“尾大不掉”吧。

 

 

這一切的不同,只能說,它們的定位不同。一個更關(guān)注Local、一個更關(guān)注Remote。Spring仍然堅持它的哲學(xué),從最基本的、大多數(shù)的場景考慮起,到特殊需要的時候,再想辦法來解決問題。它試圖找到J2EE開發(fā)和系統(tǒng)能力的均衡點。

 

 

  可以說,Spring的做法,更加合情合理。但是,我也相信,Spring在”只是為Remote注入提供簡單的支持“這一點上有點矯枉過正。我覺的,它可以做的更好,譬如通過作為J2EE標(biāo)準(zhǔn)的JNDI來封裝Local、Remote查找。

 

 

目前,Spring不怎么關(guān)心Remote Object注入,對于需要Remote注入的情況,只提供簡單的支持,而且還需要針對expert單獨寫配置信息。在這里,EJB3.0的做法,我覺的,是目前,最方便、最理智、也是最有前途的。EJB3.0通過@remote、@local就可以讓EJB Server做不同的部署。

 

 

Spring導(dǎo)出遠(yuǎn)程對象。

 

<bean class="org.springframework.remoting.rmi.RmiServiceExporter">

 

     <!-- does not necessarily have to be the same name as the bean to be exported -->

 

            <property name="serviceName"><value>AccountService</value></property>

 

               <property name="service"><ref bean="accountService"/></property>

 

               <property name="serviceInterface"><value>example.AccountService</value></property>

 

               <!-- defaults to 1099 -->

 

               <property name="registryPort"><value>1199</value></property>

 

</bean>

 

 

 

 

Spring中注入Remote是怎樣做的?

 

 

<bean class="example.SimpleObject">
            

 

               <property name="accountService"><ref bean="accountService"/></bean>
            

 

</bean>
            

 

 
            

 

<bean id="accountService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
            

 

               <property name="serviceUrl"><value>rmi://HOST:1199/AccountService</value></property>
            

 

               <property name="serviceInterface"><value>example.AccountService</value></property>
            

 

</bean>
            

 

看了,這段代碼,你就知道了。

 

 

這種方法非常的輕量級,從本質(zhì)上來說,這種方法和JNDI沒有任何的不同,這種方法,也需要一個NamingService,還記得RMI編程中,運(yùn)行服務(wù)端的時候,首先運(yùn)行rmiregistry,這個實際上就是非常簡單的NamingService??磥恚?/span>Rd JohnsonJNDI真是深惡痛絕啊。怎么也不愿意用JNDI。Spring這種方法,也許沒有JNDI那樣重量級,但是很顯然它不能支持工業(yè)級分布系統(tǒng),J2EE發(fā)展到今天,JNDI已經(jīng)成為最核心的技術(shù),它不是簡單的Object Naming Service,它提供標(biāo)準(zhǔn)接口來定位用戶、微機(jī)、網(wǎng)絡(luò)、對象、服務(wù)器等等。它已經(jīng)廣泛而深入的進(jìn)入J2EE技術(shù)的各個領(lǐng)域、成為J2EE系統(tǒng)的紐帶。

 

 

舉個很簡單的例子:我需要在Spring應(yīng)用中動態(tài)獲取Remote Object,我該怎么做?我需要無縫使用LDAP,我該怎么做?答案是,Spring不能幫到你什么。

 

 

那么我就想,Spring為什么不使用JNDI來封裝LocalRemote查找兩種協(xié)議?從而,使用J2EE標(biāo)準(zhǔn)來實現(xiàn)無縫“注入”。這樣帶來的優(yōu)點就是:(1)適應(yīng)JNDI已經(jīng)廣泛而深入滲透的領(lǐng)域(2)JNDIJ2EE標(biāo)準(zhǔn)(3)支持動態(tài)Remote Service獲取(4)支持工業(yè)級分布系統(tǒng)。

 

 

Properties props = new Properties();

 

 

pros.put(“searchServiceFactory”,”org.net.spring.bean.BeanFactory”);

 

 

Context ctx = new Context(env);

 

 

ctx.lookup(“servicename”);

 

 

 

 

 

Properties props = new Properties();

 

 

pros.put(“searchServiceFactory”,”com.sun.j2ee.jndi”);

 

 

Context ctx = new Context(env);

 

 

ctx.lookup(“servicename”);

 

 

 

 

 

 

  從下面,你可以看出,我個人認(rèn)為Spring如果仍能OS,free,也許還會有很多人選擇它,但是如果,它試圖商業(yè)化,那么可以肯定它必須向EJB3.0靠攏。向標(biāo)準(zhǔn)靠攏。

 

 

 

 

 

 

 

 

4.3 獨立的、完整的、面向ProgrammersAOP框架才是Spring真正的亮點

 

 

  EJB具有Spring中所宣揚(yáng)的AOP能力嗎?答案是肯定的。EJB的基礎(chǔ)設(shè)施就是使用AOP技術(shù)實現(xiàn)的。然而,我要說,EJBAOP并沒有面向Programmers。為什么這么說?EJB Implements為你提供一組基礎(chǔ)設(shè)施(例如,JBOSS中那些可配置的interceptors)。你可以根據(jù)系統(tǒng)需要配置。但是,你不可以編寫自己的interceptor,然后配置到系統(tǒng)中。因為EJBinterceptors往往和EJB Implements內(nèi)部愈合很緊,你想編寫自己的interceptor,意味著你必須閱讀EJB Implementssource,了解它的實現(xiàn)。換句話說,EJB Implements中的AOP技術(shù)是為了EJB Server能夠提供基礎(chǔ)設(shè)施而使用的,它沒有想到為programmer提供更多的AOP能力。而SpringAOP開始就是作為一個框架來發(fā)展的,是獨立的、完整的。造成這種情況,是歷史的原因。EJB Implements作者也不是神人,他們不可能,N年前,就想到將AOP框架設(shè)計的足夠獨立,從而面向programmes。

 

 

個人觀點:EJB3.0在基礎(chǔ)設(shè)施方面的說明,基本沿襲EJB2.X的。只是,可以提到EJB3.0支持通過annotations來使用基礎(chǔ)設(shè)施,沒有說,EJB3.0需要完善的AOP框架,但是,我想,EJB3.0 Implments應(yīng)該都會提供一個獨立的、完整的、面向programmerAOP框架。事實上,JBOSS不早就有了J

 

 

  當(dāng)然,在Spring中使用AOP也不是那么的輕松,譬如,讓你自己寫TransactionProxy,你還是需要了解Spring AOP內(nèi)部運(yùn)作機(jī)制的。

 

 

 

 

 

4.4 Spring對其它框架的集成

 

 

  這個問題,就不談了。

 

 


五、
EJB將走向何方

 

 

5.1 EJB-3.0

 

 

  我們沒必要說EJB2.X本身有多少的缺陷,畢竟,它是前一個J2EE時代的產(chǎn)物,只能說EJB2.X已經(jīng)不能反映大多數(shù)J2EE應(yīng)用的實際需要。過時了。那么EJB3.0打算帶我們走向何方?

 

 

  EJB3.0 Spec除了針對簡化開發(fā)、方便測試、方便部署等目標(biāo)做了不少的修改,更重要的是EJB3.0SessionBean,特別是EntityBean模型做了一個全面的整容手術(shù)。這種修改是革命性的。

 

 

在我的《如果我來改進(jìn)EJB2.X模型》中,我談到,如果,讓我對EJB2.XEntityBean模型做修改,那么首先需要為新的模型定好位。就拿EntityBean來說好了。 

 

 

第一條路:繼續(xù)EntityBean設(shè)計的初試?yán)砟睿?/span>Remote Domain Model(包括BMP EntityBean代表的Domain ModelCMP EntityBean代表的AnaemicDomainObject),并且保留Local接口,力圖改經(jīng)持久模型的設(shè)計,提高性能(即使CMP EntityBean的性能也是難以令人接受的,這種情況,我個人認(rèn)為,主要是因為EntityBean模型設(shè)計的不好,在我的另一篇《如果我來改進(jìn)EJB2.X模型》中有深入的分析)、增強(qiáng)功能(EJBQL實在太弱),讓那些連SessionBeanEntityBean都需要部署在不同Server上的應(yīng)用來為EJB2.XEntityBean留口氣。

 

 

但是,顯然,EJB Server提供商是不可能甘心這一點羹的,因為那樣的應(yīng)用實在太少了。事實已經(jīng)證明,如果EntityBeanRemote不是必須的,那么RemoteEntityBean性能上是不可行的,它只能工作在SessionBean后端,然而,即使EntityBean工作在SessionBean后端,但是EntityBean本身的局限性也太多,粒度要么太粗要么太細(xì),性能、功能太弱,等等,開發(fā)數(shù)據(jù)應(yīng)用非常地蹩腳,那么如果,在Remote EntityBean不是必須的情況下,我為什么不完全放棄EntityBean,在SessionBean后端使用其它的O/R Mapping Tool來開發(fā)數(shù)據(jù)應(yīng)用,譬如Hibernate。這就是,EntityBean可以走第二條路。當(dāng)然,從某種意義上來說,也是它必須走的路。

 

 

第二條路:完全拋棄EntityBean,采用Hibernate這樣的O/R Mapping Engine作為Session Bean、Message-Driven Bean的后端數(shù)據(jù)持久化工具。而從EJB3.0可以看出,EJB3.0的確完全拋棄了傳統(tǒng)的EntityBean模型。個人意見:可以這樣說吧,EntityBean已經(jīng)不復(fù)存在,Expert GroupSessionBean下給你換上了一個非常sharpPersistence engine,你拿著engine,想干什么就干什么好了(上面講過,EntityBean中,PersitenceEngineclient是通明的,這是由這兩種引擎的本質(zhì)作用決定的。有人說,EntityBean Application中不可以使用Dynamic Query,只能在配置文件中申明EJBQL,這些都是兩種Persistence Engine的本質(zhì)所決定的)。蹩腳的、強(qiáng)制模型的EntityBean不復(fù)存在!另外,EntityBean Remote特性在EJB3.0中根本沒有提到,或許只是作為一個可選特性了吧(我還沒有想到,EJB3.0中,如何來支持Remote PO,這個問題很詭異)。看來,Expert Group已經(jīng)徹底否定了EntityBean的設(shè)計,或者說EntityBean的確是不符合實際需求的,Remote EntityBean、Remote Domain Object在絕大多數(shù)情況下是不切實際的。

 

 

話外題:HibernateJDO的關(guān)系,很微妙。EJB3.0JDO的合并、Gavin進(jìn)入EJB3.0 ExpertGroup令人很迷惑。EJB3.0的持久化模型采用JDO,應(yīng)該是理所當(dāng)然的。但是,目前,EJB3.0Persitence Engine部分似乎被Hibernate左右,那么JDO的位置應(yīng)該在哪里?

 

 

 

 

 

六、Spring將走向何方

 

 

  無疑,“聽起來很美妙的”IOC、實力、實用派Spring AOP、集成大量frameworkSpring是目前、對分布式、高級J2EE特性要求不強(qiáng)的系統(tǒng)的最合理選擇。但是,你可以看到,Spring能做到的,除了集成大量framework這個特性外(當(dāng)然這個永遠(yuǎn)不會被寫進(jìn)EJB Spec,但是如果EJB Server供應(yīng)商想這樣做,也是非常簡單的事),EJB3.0也能做到,而且很多地方做的比Spring好很多,最重要的,EJB是標(biāo)準(zhǔn),所以,很肯定的說,如果Spring OSfree,保持目前的姿態(tài)發(fā)展,仍然會成為開發(fā)人員不錯的選擇,然而,如果Spring試圖商業(yè)化,我是Rd Johnson的話,我會向EJB3.0靠攏,搖身成為EJB3.0 Server提供商。

 

 

 

 

 

七、EJB3.0J2EE商用framework的未來

 

 

  大肆革新過的EJB3.0,是J2EE商用framework的將來。

 

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多