EJB(2.X-3.0)、Hibernate、Spring:剖析、批判和展望
12/28/2004于珞珈山
一、 前言
我強(qiáng)調(diào)EJB、Hibernate、Spring的恩怨情仇,同時也必須說明,我一向反感你說我怎么侵入、你說我怎么依賴式的EJB VS Hibernate、EJB VS Spring的討論,因為這種行為本身就是沒有意義的、錯誤的。我提倡從正確的技術(shù)對比和理性的技術(shù)批判中受益。對比,我們需要找準(zhǔn)對比點;批判,我們需要從source、spec、application context中分析、批判。
二、 從EJB說起
2.1 EJB幾種Bean類型的引入順序
EJB1.0,有兩種Bean類型:SessionBean、EntityBean。
EJB2.0,引入CMP EntityBean、引入Message-Driven Bean、引入Local接口。
2.2 Entity Bean和O/R Mapping的微妙關(guān)系
我想對O/R Mapping、O/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 EntityBean,EJB Server提供商會為你提供O/R Mapping 能力。而且,事實的確是這樣,任何支持CMP EntityBean的EJB Server都需要提供一個Persistence(O/R Mapping) Engine,譬如JBOSS的JAWS(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),包括SessionBean和EntityBean。它引入了很多非常前衛(wèi)的技術(shù)、概念。主要包括分布式組件、容器、DB操作的對象試圖。
EJB1.0,可能Expert Group設(shè)想的EJB的應(yīng)用場景是大規(guī)模分布式的系統(tǒng)。所以,SessionBean、EntityBean尚沒有引入Local接口。 client->SessionBean、client->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),方法各異。
EJB1.0為DB操作提供了對象試圖。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)Role,EntityBean對應(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)訪問SessionBean的WebApplication和SessionBean部署在同一服務(wù)器上的情況非常普遍,所以提供SessionBean的Local接口,也是必然的事情。2.X之后,最常用的一個Pattern就是使用SessionBean Façade通過Local的形式訪問EntityBean。而且,即使應(yīng)用規(guī)模大到連SessionBean和EntityBean都需要部署到不同的Server,也沒有關(guān)系,因為EJB2.X同樣支持Remote接口。
其次,EJB2.0引入CMP EntityBean。CMP EntityBean解決了EntityBean持久化表示和JDBC分離的問題,同時大大簡化了EntityBean的開發(fā)、提高了性能。但是,我不得不說,CMP EntityBean將EJB1.X的Domain Model理念完全沖掉了,因為CMP EntityBean是不能包含任何Domain Logic的。BMP EntityBean似乎就是Matrin所說的DomainObject,而CMP EntityBean在典型的SessionBean->EntityBean這樣的應(yīng)用場景下,似乎就是Martin所說的Transaction Script中的AnaemicDomainObject。
三、 我理解的Hibernate
本來,本文的題目叫做《EJB、Spring:剖析、批判和展望》,因為我覺的Hibernate和EJB、Spring不是一個層次的東西,雖然,這個道理很淺顯,但是為什么那么多人還拿Hibernate來攻擊EJB,來攻擊EntityBean?EntityBean是值得狠狠攻擊的,但是你用錯了槍。
我上面提到,支持CMP EntityBean的EJB Implements都有一個Persistence Engine,也就是O/R Mapping Engine。CMP 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 |
|
在這里,我建議你停下來,想想EntityBean是不是應(yīng)該對應(yīng)Hibernate中的PO/POJO?舉個例子,你修改PO后,有時是不是需要sessionObj.update(po)來更新(當(dāng)然,在非夸Session的情況下,不需要顯式的update的),這個sessionObj.update(po)是不是表示你直接使用Hibernate的Persitence Engine?是的。而在EntityBean中,你修改EntityBean后,你需要其它的行為來使得EntityBean的變化同步到DB嗎?不需要。因為,EJB Container攔截你的調(diào)用,在你更改Bean的field之前、之后,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)的、功能固定的EntityBean的O/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ù)隔離、改造。從適用范圍上來說,Spring對EJB做了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五十步笑百步?因為,我上面提到,Spring在Object很簡單的情況下,是可以任意部署的、復(fù)用的。而EJB卻不管你需不需要,開始就設(shè)想你需要的。同樣,Spring中的BeanFactoryAware、BeanNameAware等等接口也都說明了一點:Spring將特性從Object剝離,從而,盡量降低它的依賴性。只有當(dāng)你的Object復(fù)雜的時候,framework才會侵入你的Object。
針對,第二點,我想著重談一下。為什么說,從某種意義上說Spring中部署的對象是沒有狀態(tài)的?我們知道,Spring支持兩種Object:Singleton和Prototype。Spring Spec中,認(rèn)為,Singleton可以稱為stateless的,Prototype可以稱為是statefule的。而在EJB的世界中,StatefuleSessionBean和EntityBean也稱作是stateful的。那么,它們的stateful分別意味著什么?它們?yōu)槭裁丛谝蕾囆苑矫嬗心敲创蟮膮^(qū)別?為什么Spring中的Object不需要實現(xiàn)特定接口,而EJB需要?先來,看看EJB的SessionBean接口:
|
|
|
|
|
|
|
|
其中的setSessionContext我上面說過。看ejbActivate()、ejbPassive(),為什么會有這兩個函數(shù)?而Spring不需要實現(xiàn)有同樣函數(shù)的接口?這是EJB和Spring的對象管理機(jī)制的不同造成。EJB implements一般來說,為了復(fù)用Bean,會采用一級Cache加上一級InstancePool(StatelessSessionBean是不需要Cache的),從而支持將StatefulSessionBean持久化到磁盤,支持EntityBean的Bean Instance(注意這個Bean Instance和client得到的EntityBean是不同的,它沒有和任何的DB Record關(guān)聯(lián))的復(fù)用,這就導(dǎo)致了ejbAcrivate、ejbPassivate等的引入。但是,Spring沒有采用這樣管理機(jī)制,它只有Singleton/Prototype。而Prototype雖然也可以說成是Statefule的,但是它不會在不同的client中復(fù)用Object Instance,而是每一個client一個對象,哪怕一萬個client,那么就產(chǎn)生一萬個Instance,而在EJB中,可能使用100 Instance來服務(wù),將not active的Bean持久化到磁盤,復(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-method、destroy-method屬性,這樣避免和Spring框架的綁定。
總的來說,Spring從對象最基本的引用場景出發(fā),當(dāng)需要復(fù)雜特性的時候,才會采用特殊機(jī)制來解決問題,也就是在這時,才會使應(yīng)用綁定到Spring中。所以,它的侵入性比較低,但是不是“無侵入性”,不是你想的那么美好,當(dāng)然,也沒有“絕對無侵入“的framework。
4.2 我覺的Spring IOC的設(shè)計思路不夠完美
Spring的IOC被一些人當(dāng)作多么神奇的東西。
EJB具有Spring中所說的那種IOC的能力嗎?答案是肯定的。EJB中的EJB引用、資源引用、環(huán)境屬性都可以說是IOC,不是嗎?然而,Spring和EJB的IOC不同在哪里?
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 Johnson對JNDI真是深惡痛絕啊。怎么也不愿意用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來封裝Local、Remote查找兩種協(xié)議?從而,使用J2EE標(biāo)準(zhǔn)來實現(xiàn)無縫“注入”。這樣帶來的優(yōu)點就是:(1)適應(yīng)JNDI已經(jīng)廣泛而深入滲透的領(lǐng)域(2)JNDI是J2EE標(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 獨立的、完整的、面向Programmers的AOP框架才是Spring真正的亮點
EJB具有Spring中所宣揚(yáng)的AOP能力嗎?答案是肯定的。EJB的基礎(chǔ)設(shè)施就是使用AOP技術(shù)實現(xiàn)的。然而,我要說,EJB的AOP并沒有面向Programmers。為什么這么說?EJB Implements為你提供一組基礎(chǔ)設(shè)施(例如,JBOSS中那些可配置的interceptors)。你可以根據(jù)系統(tǒng)需要配置。但是,你不可以編寫自己的interceptor,然后配置到系統(tǒng)中。因為EJB的interceptors往往和EJB Implements內(nèi)部愈合很緊,你想編寫自己的interceptor,意味著你必須閱讀EJB Implements的source,了解它的實現(xiàn)。換句話說,EJB Implements中的AOP技術(shù)是為了EJB Server能夠提供基礎(chǔ)設(shè)施而使用的,它沒有想到為programmer提供更多的AOP能力。而Spring的AOP開始就是作為一個框架來發(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)該都會提供一個獨立的、完整的、面向programmer的AOP框架。事實上,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.0對SessionBean,特別是EntityBean模型做了一個全面的整容手術(shù)。這種修改是革命性的。
在我的《如果我來改進(jìn)EJB2.X模型》中,我談到,如果,讓我對EJB2.X的EntityBean模型做修改,那么首先需要為新的模型定好位。就拿EntityBean來說好了。
第一條路:繼續(xù)EntityBean設(shè)計的初試?yán)砟睿?/span>Remote Domain Model(包括BMP EntityBean代表的Domain Model和CMP EntityBean代表的AnaemicDomainObject),并且保留Local接口,力圖改經(jīng)持久模型的設(shè)計,提高性能(即使CMP EntityBean的性能也是難以令人接受的,這種情況,我個人認(rèn)為,主要是因為EntityBean模型設(shè)計的不好,在我的另一篇《如果我來改進(jìn)EJB2.X模型》中有深入的分析)、增強(qiáng)功能(EJBQL實在太弱),讓那些連SessionBean、EntityBean都需要部署在不同Server上的應(yīng)用來為EJB2.X的EntityBean留口氣。
但是,顯然,EJB Server提供商是不可能甘心這一點羹的,因為那樣的應(yīng)用實在太少了。事實已經(jīng)證明,如果EntityBean的Remote不是必須的,那么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 Group在SessionBean下給你換上了一個非常sharp的Persistence engine,你拿著engine,想干什么就干什么好了(上面講過,EntityBean中,PersitenceEngine對client是通明的,這是由這兩種引擎的本質(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ù)情況下是不切實際的。
話外題:Hibernate和JDO的關(guān)系,很微妙。EJB3.0和JDO的合并、Gavin進(jìn)入EJB3.0 ExpertGroup令人很迷惑。EJB3.0的持久化模型采用JDO,應(yīng)該是理所當(dāng)然的。但是,目前,EJB3.0的Persitence Engine部分似乎被Hibernate左右,那么JDO的位置應(yīng)該在哪里?
|
六、Spring將走向何方
無疑,“聽起來很美妙的”IOC、實力、實用派Spring AOP、集成大量framework的Spring是目前、對分布式、高級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 OS、free,保持目前的姿態(tài)發(fā)展,仍然會成為開發(fā)人員不錯的選擇,然而,如果Spring試圖商業(yè)化,我是Rd Johnson的話,我會向EJB3.0靠攏,搖身成為EJB3.0 Server提供商。
七、EJB3.0是J2EE商用framework的未來
大肆革新過的EJB3.0,是J2EE商用framework的將來。
|