免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
EJB(2.X-3.0)、Hibernate、Spring:剖析、批判和展望
TomHornson#(at)#hotmai.com
 
 
12/28/2004于珞珈山
 
 
 
 
一段時(shí)間以來(lái),EJB、Hibernate、Spring的恩怨情仇,是J2EE的熱門(mén)話題。EJB VS Hibernate、EJB VS Spring這
樣的議題隨處可在。這篇文章,筆者試圖通過(guò)對(duì)技術(shù)發(fā)展史的回顧,對(duì)source的剖析、對(duì)比,深入挖掘這些技術(shù)出現(xiàn)的初衷、缺陷、走向。
 
 
一、    前言
 
 
我強(qiáng)調(diào)EJB、Hibernate、Spring的恩怨情仇,同時(shí)也必須說(shuō)明,我一向反感你說(shuō)我怎么侵入、你說(shuō)我怎么依賴式的EJB VS Hibernate、EJB VS Spring的討論,因?yàn)檫@種行為本身就是沒(méi)有意義的、錯(cuò)誤的。我提倡從正確的技術(shù)對(duì)比和理性的技術(shù)批判中受益。對(duì)比,我們需要找準(zhǔn)對(duì)比點(diǎn);批判,我們需要從source、spec、application context中分析、批判。
 
 
 
 
二、    從EJB說(shuō)起
 
 
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)系
 
 
我想對(duì)O/R Mapping、O/R Mapping Engine做一個(gè)簡(jiǎn)要的說(shuō)明。
 
 
O/R Mapping,以對(duì)象視圖(Object View)來(lái)看待DB Record,對(duì)象操作能夠通明地映射成DB Record操作。
 
 
O/R Mapping Engine,就是使得O/R Mapping成為可能的具體實(shí)現(xiàn)手法。
 
 
從我們的定義來(lái)看,使用BMP EntityBean意味著你自己在實(shí)施一個(gè)非常簡(jiǎn)單的O/R Mapping ,你自己在為能夠以對(duì)象視圖和DB交互做出努力。而為了支持CMP EntityBean,EJB Server提供商會(huì)為你提供O/R Mapping 能力。而且,事實(shí)的確是這樣,任何支持CMP EntityBean的EJB Server都需要提供一個(gè)Persistence(O/R Mapping) Engine,譬如JBOSS的JAWS(Just Another Web Store)。
 
 
至于,Hibernate、IBATIS等,雖然,也叫做O/R Mapping Tool,但是它們的意義已經(jīng)遠(yuǎn)遠(yuǎn)超過(guò)了CMP EntityBean O/R Mapping Engine這樣的Tool。下面會(huì)有詳細(xì)的分析。
 
 
 
 
2.3 EJB-1.0
 
 
EJB1.0是分布式組件架構(gòu),包括SessionBean和EntityBean。它引入了很多非常前衛(wèi)的技術(shù)、概念。主要包括分布式組件、容器、DB操作的對(duì)象試圖。
 
 
EJB1.0,可能Expert Group設(shè)想的EJB的應(yīng)用場(chǎng)景是大規(guī)模分布式的系統(tǒng)。所以,SessionBean、EntityBean尚沒(méi)有引入Local接口。 client->SessionBean、client->EntityBean、SessionBean->SessionBean、SessionBean->EntityBean等等都是remote的。
 
 
EJB1.0,將容器這個(gè)概念引入EJB,意義重大。這里我想順便澄清一個(gè)問(wèn)題:容器是什么?我的觀點(diǎn):容器只是一個(gè)概念、一種架構(gòu)。就拿EJB Server來(lái)說(shuō),Server試圖為Bean提供分布式、事務(wù)、安全等基礎(chǔ)設(shè)施,那么就必須有一個(gè)凌駕于Bean之上的Layer或者說(shuō)warp,這樣才能夠從高層攔截Bean調(diào)用,進(jìn)行一些額外操作。這樣的架構(gòu)就叫做容器架構(gòu),這個(gè)概念當(dāng)然不是自EJB才有的。至于怎樣實(shí)現(xiàn),方法各異。
 
 
 
 
事實(shí)上,以個(gè)人的觀點(diǎn),容器架構(gòu)的核心,不在于從高層“掌握”Beans(Objects),而在于采用怎樣的技術(shù)來(lái)實(shí)現(xiàn)Bean(Object)調(diào)用的攔截。無(wú)疑,EJB Servers和Spring的實(shí)現(xiàn)手法是不同的。下面會(huì)詳細(xì)討論這個(gè)問(wèn)題。
 
 
 
 
EJB1.0為DB操作提供了對(duì)象試圖。Expert Group當(dāng)初是怎樣定位EntityBean的?無(wú)疑,1.0中的EntityBean,也就是2.0以后的BMP EntityBean,定位是Domain Object(我不知道當(dāng)時(shí)有沒(méi)有這個(gè)概念,只是它們的思想是非常一致)。它的fields直接映射DB Table Schema,member functions就是對(duì)Table Record的操作。Client->EntityBean、SessionBean->EntityBean等就可以直接和數(shù)據(jù)庫(kù)交互了。
 
 
有人跟我說(shuō)EJB1.0基于Catalysis方法學(xué),SessionBean對(duì)應(yīng)Role,EntityBean對(duì)應(yīng)Domain Object。到目前為止,我對(duì)這種說(shuō)法,持保留態(tài)度,因?yàn)镋JB Spec中,我絲毫沒(méi)有這種說(shuō)法的痕跡。
 
 
 
 
2.4 EJB-2.X
 
 
無(wú)疑,EJB1.X的設(shè)計(jì)存在重大的缺陷。2.0增加的特性包括Local接口、CMP EntityBean,它們是對(duì)1.x缺陷的重大更正。
 
 
首先,事實(shí)上沒(méi)有多少Expert Group想象中的大規(guī)模分布式應(yīng)用。我們從兩個(gè)方面來(lái)說(shuō):(1)通過(guò)Remote方式使用 EntityBean引起嚴(yán)重的性能問(wèn)題,很有必要提供Local接口。(2)訪問(wèn)SessionBean的WebApplication和SessionBean部署在同一服務(wù)器上的情況非常普遍,所以提供SessionBean的Local接口,也是必然的事情。2.X之后,最常用的一個(gè)Pattern就是使用SessionBean Façade通過(guò)Local的形式訪問(wèn)EntityBean。而且,即使應(yīng)用規(guī)模大到連SessionBean和EntityBean都需要部署到不同的Server,也沒(méi)有關(guān)系,因?yàn)镋JB2.X同樣支持Remote接口。
 
 
其次,EJB2.0引入CMP EntityBean。CMP EntityBean解決了EntityBean持久化表示和JDBC分離的問(wèn)題,同時(shí)大大簡(jiǎn)化了EntityBean的開(kāi)發(fā)、提高了性能。但是,我不得不說(shuō),CMP EntityBean將EJB1.X的Domain Model理念完全沖掉了,因?yàn)镃MP EntityBean是不能包含任何Domain Logic的。BMP EntityBean似乎就是Matrin所說(shuō)的DomainObject,而CMP EntityBean在典型的SessionBean->EntityBean這樣的應(yīng)用場(chǎng)景下,似乎就是Martin所說(shuō)的Transaction  Script中的AnaemicDomainObject。
 
 
順便說(shuō)一下,我個(gè)人是不同意Martin的RichDomainObject的說(shuō)法。因?yàn)?,在?shù)據(jù)應(yīng)用系統(tǒng)中,Martin提到的相對(duì)于Transacton Script中AnaemicDomainObject的RichDomainModel往往沒(méi)有反映現(xiàn)實(shí)世界。一個(gè)Bank Account反映到現(xiàn)實(shí)世界,就是賬本中的一條記錄,它沒(méi)有自發(fā)的動(dòng)作,譬如withdraw。它和Person不同,Person可以有say(String words)這樣的自發(fā)動(dòng)作。Account的withdraw應(yīng)該放到AccountManager中,由AccountManger來(lái)操作Account。不是說(shuō)OO中的Object都需要有動(dòng)作,現(xiàn)實(shí)世界中,本來(lái)就有靜態(tài)的、沒(méi)有自發(fā)動(dòng)作的事物,譬如一個(gè)賬本、一個(gè)賬號(hào)、一個(gè)資料庫(kù)。雖然,不可否認(rèn),Rich Domain Model(對(duì)比AnaemicDomainObject說(shuō)的)能夠帶來(lái)不少的好處(什么樣的好處,你看看Martin的《Domain Logic and SQL》,就知道了)。
 
 
 
 
三、    我理解的Hibernate
 
 
本來(lái),本文的題目叫做《EJB、Spring:剖析、批判和展望》,因?yàn)槲矣X(jué)的Hibernate和EJB、Spring不是一個(gè)層次的東西,雖然,這個(gè)道理很淺顯,但是為什么那么多人還拿Hibernate來(lái)攻擊EJB,來(lái)攻擊EntityBean?EntityBean是值得狠狠攻擊的,但是你用錯(cuò)了槍。
 
 
我上面提到,支持CMP EntityBean的EJB Implements都有一個(gè)Persistence Engine,也就是O/R Mapping Engine。CMP O/R Mapping Engine用來(lái)做什么的?它通過(guò)分析CMP Abastract Schema、分析EJBQL、分析Bean狀態(tài)等行為,生成SQL,然后和DB 進(jìn)行交互。
 
 
而在我眼里,Hibernate不是”O/R Mapping Tool”這幾個(gè)字能概括的了。我說(shuō)Hibernate是一款獨(dú)當(dāng)一面的輕量級(jí)翻譯中間件,是Layer,和CMP EntityBean O/R Mapping Engine不是一個(gè)層次的東西了。
 
 
Application------->CMP EntityBean Operation-------->DB
|
(O/R Mapping Engine)
 
 
 
|---HQL、Criteria Query
 
 
Application------> Hibernate ------> |---POJO/PO Operation---------> DB
 
 
|---and so on
 
 
通過(guò)上面的兩個(gè)圖,你看出區(qū)別來(lái)了嗎?
 
 
EntityBean應(yīng)用,不知道O/R Mapping Engine的存在,只需要使用EntityBean來(lái)完成交互。
 
 
而在Hibernate應(yīng)用中,Application是直接使用Hibernate的。也就是說(shuō),它是直接使用O/R Mapping Engine的。
 
 
在這里,我建議你停下來(lái),想想EntityBean是不是應(yīng)該對(duì)應(yīng)Hibernate中的PO/POJO?舉個(gè)例子,你修改PO后,有時(shí)是不是需要sessionObj.update(po)來(lái)更新(當(dāng)然,在非夸Session的情況下,不需要顯式的update的),這個(gè)sessionObj.update(po)是不是表示你直接使用Hibernate的Persitence Engine?是的。而在EntityBean中,你修改EntityBean后,你需要其它的行為來(lái)使得EntityBean的變化同步到DB嗎?不需要。因?yàn)?,EJB Container攔截你的調(diào)用,在你更改Bean的field之前、之后,container會(huì)調(diào)用load/store方法的(當(dāng)然,在BMP/CMP EntityBean中,情況是不同的,BMP EntityBean調(diào)用programmer自己用JDBC編寫(xiě)的load/store等方法,而CMP EntityBean,使用CMP Peristence Engine來(lái)做這個(gè)工作)。這樣,就隱式的持久化數(shù)據(jù)了。不需要,你像Hibernate那樣調(diào)用session.update這樣的語(yǔ)句。EntityBean這種同步方式是對(duì)它性能差的重要原因之一。值得注意的是,EJB Implements對(duì)于EntityBean同步并不完全是我上面描述的那樣,同步的頻率和事務(wù)、特定的implements是緊密相關(guān)的。
 
 
總的來(lái)說(shuō),CMP EntityBean O/R Mapping Engine是為靜態(tài)的、功能固定的EntityBean的O/R Mapping提供支持而開(kāi)發(fā)的。而Hibernate擔(dān)任的是一個(gè)Layer的作用。
 
 
 
 
四、    Spring不是神話
 
 
Rd Johnson聰明在哪里?聰明在,他堅(jiān)持了自己的實(shí)踐,而不是隨大流。Rd Johnson認(rèn)識(shí)到90%的應(yīng)用不需要分布式、不需要J2EE中那些重量級(jí)的技術(shù),譬如JNDI,他就動(dòng)手為EJB脫去Remote這層皮、將大多數(shù)應(yīng)用中不必要的技術(shù)隔離、改造。從適用范圍上來(lái)說(shuō),Spring對(duì)EJB做了90%的補(bǔ)充。
 
 
個(gè)人看法:Spring的哲學(xué)在于,framework針對(duì)最常見(jiàn)、最簡(jiǎn)單的應(yīng)用場(chǎng)景而設(shè)計(jì),等到需要特殊技術(shù)的時(shí)候,再想辦法解決問(wèn)題。這樣,在絕大多數(shù)沒(méi)有特殊要求的應(yīng)用中,Spring就顯示出優(yōu)勢(shì)來(lái)了。下面,我們會(huì)做詳細(xì)的講解。
 
 
 
 
4.1 Spring“無(wú)侵入性“是謊言,但是有資格笑”百步之外的EJB”
 
 
“無(wú)侵入性”是Spring標(biāo)榜的特性。但是,我想說(shuō),Spring的“無(wú)侵入”是謊言,隨著應(yīng)用的深入,“無(wú)侵入”對(duì)什么framework來(lái)說(shuō),都是個(gè)神化。
 
 
什么就叫“無(wú)侵入性”?部署到Spring中的Object不需要強(qiáng)制任何實(shí)現(xiàn)接口就可以說(shuō)Spring是“無(wú)侵入性”的?我覺(jué)的,這是大錯(cuò)特錯(cuò)。如果你非要說(shuō),Spring的確不需要像EJB那樣強(qiáng)制實(shí)現(xiàn)一些接口,那么我只能告訴你:
 
 
(1)Spring設(shè)想的Object的應(yīng)用場(chǎng)景是從最簡(jiǎn)單的出發(fā)。所以,它沒(méi)有,為了一些預(yù)料中要使用的特性而強(qiáng)制Object實(shí)現(xiàn)一些特定的接口。但是,事實(shí)上,在Spring中,如果你的應(yīng)用場(chǎng)景稍微深入一點(diǎn),那么你就和和Spring綁定了。
 
 
(2)Spring管理的Object,從某種意義上說(shuō)是沒(méi)有狀態(tài)的。
 
 
針對(duì)第一點(diǎn),我舉兩個(gè)個(gè)例子。(1)EJB內(nèi)部方法的調(diào)用,會(huì)導(dǎo)致基礎(chǔ)設(shè)施不會(huì)起作用。但是Bean接口(SessionBean、EntityBean、MessageDrivenBean)中都有可以使Bean獲得自己Context的支持,譬如:SessionBean的setSessionContext(SessionContext ctx) 等等,容器部署B(yǎng)ean的時(shí)候會(huì)通過(guò)它給每個(gè)Bean設(shè)置一個(gè)上下文。而EJBContext中,有EJBObject getEJBObject這樣的函數(shù),可以使得Bean獲得自身的EJBObject,這樣通過(guò)EJBObject來(lái)調(diào)用Bean自己的函數(shù),基礎(chǔ)設(shè)施就會(huì)起作用了。而Spring中,如果,一個(gè)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)你需要上面說(shuō)的內(nèi)部調(diào)用需要基礎(chǔ)設(shè)施起作用的特性,不管在EJB還是Spring肯定需要和特定框架綁定的。為什么說(shuō),Spring五十步笑百步?因?yàn)?,我上面提到,Spring在Object很簡(jiǎn)單的情況下,是可以任意部署的、復(fù)用的。而EJB卻不管你需不需要,開(kāi)始就設(shè)想你需要的。同樣,Spring中的BeanFactoryAware、BeanNameAware等等接口也都說(shuō)明了一點(diǎn):Spring將特性從Object剝離,從而,盡量降低它的依賴性。只有當(dāng)你的Object復(fù)雜的時(shí)候,framework才會(huì)侵入你的Object。
 
 
針對(duì),第二點(diǎn),我想著重談一下。為什么說(shuō),從某種意義上說(shuō)Spring中部署的對(duì)象是沒(méi)有狀態(tài)的?我們知道,Spring支持兩種Object:Singleton和Prototype。Spring Spec中,認(rèn)為,Singleton可以稱為stateless的,Prototype可以稱為是statefule的。而在EJB的世界中,StatefuleSessionBean和EntityBean也稱作是stateful的。那么,它們的stateful分別意味著什么?它們?yōu)槭裁丛谝蕾囆苑矫嬗心敲创蟮膮^(qū)別?為什么Spring中的Object不需要實(shí)現(xiàn)特定接口,而EJB需要?先來(lái),看看EJB的SessionBean接口:
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我上面說(shuō)過(guò)??磂jbActivate()、ejbPassive(),為什么會(huì)有這兩個(gè)函數(shù)?而Spring不需要實(shí)現(xiàn)有同樣函數(shù)的接口?這是EJB和Spring的對(duì)象管理機(jī)制的不同造成。EJB implements一般來(lái)說(shuō),為了復(fù)用Bean,會(huì)采用一級(jí)Cache加上一級(jí)InstancePool(StatelessSessionBean是不需要Cache的),從而支持將StatefulSessionBean持久化到磁盤(pán),支持EntityBean的Bean Instance(注意這個(gè)Bean Instance和client得到的EntityBean是不同的,它沒(méi)有和任何的DB Record關(guān)聯(lián))的復(fù)用,這就導(dǎo)致了ejbAcrivate、ejbPassivate等的引入。但是,Spring沒(méi)有采用這樣管理機(jī)制,它只有Singleton/Prototype。而Prototype雖然也可以說(shuō)成是Statefule的,但是它不會(huì)在不同的client中復(fù)用Object Instance,而是每一個(gè)client一個(gè)對(duì)象,哪怕一萬(wàn)個(gè)client,那么就產(chǎn)生一萬(wàn)個(gè)Instance,而在EJB中,可能使用100 Instance來(lái)服務(wù),將not active的Bean持久化到磁盤(pán),復(fù)用Bean Instance。還請(qǐng)注意,這里我不是說(shuō)EJB中的StatefuleSessionBean好,事實(shí)上我發(fā)現(xiàn),一般來(lái)說(shuō),當(dāng)并發(fā)量很大時(shí),采用節(jié)約內(nèi)存而持久化Bean到磁盤(pán)這種策略,I/O瓶頸引起的問(wèn)題更為嚴(yán)重。
 
 
再看,ejbRemove,這個(gè)沒(méi)什么多說(shuō)的,Spring中你可以選擇實(shí)現(xiàn)InitializingBean、DisposableBean接口,但是Spring推薦不要這樣做,可以寫(xiě)普通的init成員函數(shù),然后在配置文件中指明init-method、destroy-method屬性,這樣避免和Spring框架的綁定。
 
 
總的來(lái)說(shuō),Spring從對(duì)象最基本的引用場(chǎng)景出發(fā),當(dāng)需要復(fù)雜特性的時(shí)候,才會(huì)采用特殊機(jī)制來(lái)解決問(wèn)題,也就是在這時(shí),才會(huì)使應(yīng)用綁定到Spring中。所以,它的侵入性比較低,但是不是“無(wú)侵入性”,不是你想的那么美好,當(dāng)然,也沒(méi)有“絕對(duì)無(wú)侵入“的framework。
 
 
 
 
4.2 我覺(jué)的Spring IOC的設(shè)計(jì)思路不夠完美
 
 
Spring的IOC被一些人當(dāng)作多么神奇的東西。
 
 
EJB具有Spring中所說(shuō)的那種IOC的能力嗎?答案是肯定的。EJB中的EJB引用、資源引用、環(huán)境屬性都可以說(shuō)是IOC,不是嗎?然而,Spring和EJB的IOC不同在哪里?
 
 
Spring注入的特色:主要考慮Local Object的查找,這個(gè)時(shí)候不需要任何的協(xié)議(譬如JNDI),當(dāng)你需要注入Remote Object的時(shí)候,采用RMI協(xié)議或者使用第三方Tool(譬如Hessian)。
 
 
EJB的特色:無(wú)論你的Bean-Bean是否部署在同一臺(tái)機(jī)器上、Client->Bean是否在同一臺(tái)機(jī)器上,肯定需要通過(guò)JNDI來(lái)查詢Bean,只是,如果是它們?cè)谕慌_(tái)機(jī)器上的時(shí)候,你使用Local接口,這樣使得調(diào)用變?yōu)長(zhǎng)ocal調(diào)用,從而提升性能。EJB它從出生時(shí)起,就定位為分布式組件架構(gòu),一頭栽進(jìn)“distributed”不容易出來(lái)了。這個(gè)可能就叫“尾大不掉”吧。
 
 
這一切的不同,只能說(shuō),它們的定位不同。一個(gè)更關(guān)注Local、一個(gè)更關(guān)注Remote。Spring仍然堅(jiān)持它的哲學(xué),從最基本的、大多數(shù)的場(chǎng)景考慮起,到特殊需要的時(shí)候,再想辦法來(lái)解決問(wèn)題。它試圖找到J2EE開(kāi)發(fā)和系統(tǒng)能力的均衡點(diǎn)。
 
 
可以說(shuō),Spring的做法,更加合情合理。但是,我也相信,Spring在”只是為Remote注入提供簡(jiǎn)單的支持“這一點(diǎn)上有點(diǎn)矯枉過(guò)正。我覺(jué)的,它可以做的更好,譬如通過(guò)作為J2EE標(biāo)準(zhǔn)的JNDI來(lái)封裝Local、Remote查找。
 
 
目前,Spring不怎么關(guān)心Remote Object注入,對(duì)于需要Remote注入的情況,只提供簡(jiǎn)單的支持,而且還需要針對(duì)expert單獨(dú)寫(xiě)配置信息。在這里,EJB3.0的做法,我覺(jué)的,是目前,最方便、最理智、也是最有前途的。EJB3.0通過(guò)@remote、@local就可以讓EJB Server做不同的部署。
 
 
Spring導(dǎo)出遠(yuǎn)程對(duì)象。
 
<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>
 
看了,這段代碼,你就知道了。
 
 
這種方法非常的輕量級(jí),從本質(zhì)上來(lái)說(shuō),這種方法和JNDI沒(méi)有任何的不同,這種方法,也需要一個(gè)NamingService,還記得RMI編程中,運(yùn)行服務(wù)端的時(shí)候,首先運(yùn)行rmiregistry,這個(gè)實(shí)際上就是非常簡(jiǎn)單的NamingService??磥?lái),Rd Johnson對(duì)JNDI真是深惡痛絕啊。怎么也不愿意用JNDI。Spring這種方法,也許沒(méi)有JNDI那樣重量級(jí),但是很顯然它不能支持工業(yè)級(jí)分布系統(tǒng),J2EE發(fā)展到今天,JNDI已經(jīng)成為最核心的技術(shù),它不是簡(jiǎn)單的Object Naming Service,它提供標(biāo)準(zhǔn)接口來(lái)定位用戶、微機(jī)、網(wǎng)絡(luò)、對(duì)象、服務(wù)器等等。它已經(jīng)廣泛而深入的進(jìn)入J2EE技術(shù)的各個(gè)領(lǐng)域、成為J2EE系統(tǒng)的紐帶。
 
 
舉個(gè)很簡(jiǎn)單的例子:我需要在Spring應(yīng)用中動(dòng)態(tài)獲取Remote Object,我該怎么做?我需要無(wú)縫使用LDAP,我該怎么做?答案是,Spring不能幫到你什么。
 
 
那么我就想,Spring為什么不使用JNDI來(lái)封裝Local、Remote查找兩種協(xié)議?從而,使用J2EE標(biāo)準(zhǔn)來(lái)實(shí)現(xiàn)無(wú)縫“注入”。這樣帶來(lái)的優(yōu)點(diǎn)就是:(1)適應(yīng)JNDI已經(jīng)廣泛而深入滲透的領(lǐng)域(2)JNDI是J2EE標(biāo)準(zhǔn)(3)支持動(dòng)態(tài)Remote Service獲取(4)支持工業(yè)級(jí)分布系統(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”);
 
 
 
 
從下面,你可以看出,我個(gè)人認(rèn)為Spring如果仍能OS,free,也許還會(huì)有很多人選擇它,但是如果,它試圖商業(yè)化,那么可以肯定它必須向EJB3.0靠攏。向標(biāo)準(zhǔn)靠攏。
 
 
 
 
 
 
4.3 獨(dú)立的、完整的、面向Programmers的AOP框架才是Spring真正的亮點(diǎn)
 
 
EJB具有Spring中所宣揚(yáng)的AOP能力嗎?答案是肯定的。EJB的基礎(chǔ)設(shè)施就是使用AOP技術(shù)實(shí)現(xiàn)的。然而,我要說(shuō),EJB的AOP并沒(méi)有面向Programmers。為什么這么說(shuō)?EJB Implements為你提供一組基礎(chǔ)設(shè)施(例如,JBOSS中那些可配置的interceptors)。你可以根據(jù)系統(tǒng)需要配置。但是,你不可以編寫(xiě)自己的interceptor,然后配置到系統(tǒng)中。因?yàn)镋JB的interceptors往往和EJB Implements內(nèi)部愈合很緊,你想編寫(xiě)自己的interceptor,意味著你必須閱讀EJB Implements的source,了解它的實(shí)現(xiàn)。換句話說(shuō),EJB Implements中的AOP技術(shù)是為了EJB Server能夠提供基礎(chǔ)設(shè)施而使用的,它沒(méi)有想到為programmer提供更多的AOP能力。而Spring的AOP開(kāi)始就是作為一個(gè)框架來(lái)發(fā)展的,是獨(dú)立的、完整的。造成這種情況,是歷史的原因。EJB Implements作者也不是神人,他們不可能,N年前,就想到將AOP框架設(shè)計(jì)的足夠獨(dú)立,從而面向programmes。
 
 
個(gè)人觀點(diǎn):EJB3.0在基礎(chǔ)設(shè)施方面的說(shuō)明,基本沿襲EJB2.X的。只是,可以提到EJB3.0支持通過(guò)annotations來(lái)使用基礎(chǔ)設(shè)施,沒(méi)有說(shuō),EJB3.0需要完善的AOP框架,但是,我想,EJB3.0 Implments應(yīng)該都會(huì)提供一個(gè)獨(dú)立的、完整的、面向programmer的AOP框架。事實(shí)上,JBOSS不早就有了J
 
 
當(dāng)然,在Spring中使用AOP也不是那么的輕松,譬如,讓你自己寫(xiě)TransactionProxy,你還是需要了解Spring AOP內(nèi)部運(yùn)作機(jī)制的。
 
 
 
 
4.4 Spring對(duì)其它框架的集成
 
 
這個(gè)問(wèn)題,就不談了。
 
 
五、EJB將走向何方
 
 
5.1 EJB-3.0
 
 
我們沒(méi)必要說(shuō)EJB2.X本身有多少的缺陷,畢竟,它是前一個(gè)J2EE時(shí)代的產(chǎn)物,只能說(shuō)EJB2.X已經(jīng)不能反映大多數(shù)J2EE應(yīng)用的實(shí)際需要。過(guò)時(shí)了。那么EJB3.0打算帶我們走向何方?
 
 
EJB3.0 Spec除了針對(duì)簡(jiǎn)化開(kāi)發(fā)、方便測(cè)試、方便部署等目標(biāo)做了不少的修改,更重要的是EJB3.0對(duì)SessionBean,特別是EntityBean模型做了一個(gè)全面的整容手術(shù)。這種修改是革命性的。
 
 
在我的《如果我來(lái)改進(jìn)EJB2.X模型》中,我談到,如果,讓我對(duì)EJB2.X的EntityBean模型做修改,那么首先需要為新的模型定好位。就拿EntityBean來(lái)說(shuō)好了。
 
 
第一條路:繼續(xù)EntityBean設(shè)計(jì)的初試?yán)砟睿篟emote Domain Model(包括BMP EntityBean代表的Domain Model和CMP EntityBean代表的AnaemicDomainObject),并且保留Local接口,力圖改經(jīng)持久模型的設(shè)計(jì),提高性能(即使CMP EntityBean的性能也是難以令人接受的,這種情況,我個(gè)人認(rèn)為,主要是因?yàn)镋ntityBean模型設(shè)計(jì)的不好,在我的另一篇《如果我來(lái)改進(jìn)EJB2.X模型》中有深入的分析)、增強(qiáng)功能(EJBQL實(shí)在太弱),讓那些連SessionBean、EntityBean都需要部署在不同Server上的應(yīng)用來(lái)為EJB2.X的EntityBean留口氣。
 
 
但是,顯然,EJB Server提供商是不可能甘心這一點(diǎn)羹的,因?yàn)槟菢拥膽?yīng)用實(shí)在太少了。事實(shí)已經(jīng)證明,如果EntityBean的Remote不是必須的,那么RemoteEntityBean性能上是不可行的,它只能工作在SessionBean后端,然而,即使EntityBean工作在SessionBean后端,但是EntityBean本身的局限性也太多,粒度要么太粗要么太細(xì),性能、功能太弱,等等,開(kāi)發(fā)數(shù)據(jù)應(yīng)用非常地蹩腳,那么如果,在Remote EntityBean不是必須的情況下,我為什么不完全放棄EntityBean,在SessionBean后端使用其它的O/R Mapping Tool來(lái)開(kāi)發(fā)數(shù)據(jù)應(yīng)用,譬如Hibernate。這就是,EntityBean可以走第二條路。當(dāng)然,從某種意義上來(lái)說(shuō),也是它必須走的路。
 
 
第二條路:完全拋棄EntityBean,采用Hibernate這樣的O/R Mapping Engine作為Session Bean、Message-Driven Bean的后端數(shù)據(jù)持久化工具。而從EJB3.0可以看出,EJB3.0的確完全拋棄了傳統(tǒng)的EntityBean模型。個(gè)人意見(jiàn):可以這樣說(shuō)吧,EntityBean已經(jīng)不復(fù)存在,Expert Group在SessionBean下給你換上了一個(gè)非常sharp的Persistence engine,你拿著engine,想干什么就干什么好了(上面講過(guò),EntityBean中,PersitenceEngine對(duì)client是通明的,這是由這兩種引擎的本質(zhì)作用決定的。有人說(shuō),EntityBean Application中不可以使用Dynamic Query,只能在配置文件中申明EJBQL,這些都是兩種Persistence Engine的本質(zhì)所決定的)。蹩腳的、強(qiáng)制模型的EntityBean不復(fù)存在!另外,EntityBean Remote特性在EJB3.0中根本沒(méi)有提到,或許只是作為一個(gè)可選特性了吧(我還沒(méi)有想到,EJB3.0中,如何來(lái)支持Remote PO,這個(gè)問(wèn)題很詭異)??磥?lái),Expert Group已經(jīng)徹底否定了EntityBean的設(shè)計(jì),或者說(shuō)EntityBean的確是不符合實(shí)際需求的,Remote EntityBean、Remote Domain Object在絕大多數(shù)情況下是不切實(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將走向何方
 
 
無(wú)疑,“聽(tīng)起來(lái)很美妙的”IOC、實(shí)力、實(shí)用派Spring AOP、集成大量framework的Spring是目前、對(duì)分布式、高級(jí)J2EE特性要求不強(qiáng)的系統(tǒng)的最合理選擇。但是,你可以看到,Spring能做到的,除了集成大量framework這個(gè)特性外(當(dāng)然這個(gè)永遠(yuǎn)不會(huì)被寫(xiě)進(jìn)EJB Spec,但是如果EJB Server供應(yīng)商想這樣做,也是非常簡(jiǎn)單的事),EJB3.0也能做到,而且很多地方做的比Spring好很多,最重要的,EJB是標(biāo)準(zhǔn),所以,很肯定的說(shuō),如果Spring OS、free,保持目前的姿態(tài)發(fā)展,仍然會(huì)成為開(kāi)發(fā)人員不錯(cuò)的選擇,然而,如果Spring試圖商業(yè)化,我是Rd Johnson的話,我會(huì)向EJB3.0靠攏,搖身成為EJB3.0 Server提供商。
 
 
 
 
七、EJB3.0是J2EE商用framework的未來(lái)
 
 
大肆革新過(guò)的EJB3.0,是J2EE商用framework的將來(lái)。
 
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
應(yīng)聘Java筆試時(shí)可能出現(xiàn)問(wèn)題及其答案(第二版part three)
EJB 筆記 -Chapter03 會(huì)話Bean
EJB3與EJB2架構(gòu)對(duì)比
J2EE 組件開(kāi)發(fā):會(huì)話EJB
MyEclipse開(kāi)發(fā)EJB2之CMP實(shí)體bean - whistler - BlogJav...
《J2EE面試題集錦(附答案)》-
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服