EJB儼然成為了一個(gè)任人打扮的小姑娘?,F(xiàn)在你只要和一個(gè)國(guó)內(nèi)Java開發(fā)人員交流,基本都能聽(tīng)到他們說(shuō)EJB的缺點(diǎn),即使他沒(méi)有使用過(guò)。
為此我花了點(diǎn)時(shí)間,試圖分析下EJB的優(yōu)點(diǎn)和缺點(diǎn),以及EJB對(duì)Java技術(shù)社區(qū)的貢獻(xiàn)。
我使用了EJB有6年時(shí)間,從接觸Java就開始學(xué)習(xí)EJB,使用過(guò)EJB1,EJB2和EJB3。
我總結(jié)的EJB(EJB1和EJB2)存在的問(wèn)題有:
編成模型復(fù)雜
開發(fā)和移植困難
部署描述符陷阱
類加載陷阱
測(cè)試?yán)щy
破壞面向?qū)ο笤O(shè)計(jì)
部署慢
運(yùn)行時(shí)需要EJB容器,代價(jià)高
維護(hù)困難
學(xué)習(xí)曲線大
下面我們逐一分析
一 目標(biāo)定位不清
假如你看過(guò)EJB早期規(guī)范,你會(huì)發(fā)現(xiàn),規(guī)范中隊(duì)EJB的目標(biāo)定位有11項(xiàng)之多。為了分析方便,我引用了EJB2.1版本中有關(guān)EJB目標(biāo)定義的內(nèi)容(注:序號(hào)是我加上的)。
The Enterprise JavaBeans (EJB) architecture has the following goals:
1)The Enterprise JavaBeans architecture will be the standard component architecture for build-
ing distributed object-oriented business applications in the Java programming language.
2)The Enterprise JavaBeans architecture will support the development, deployment, and use of
web services.
3)The Enterprise JavaBeans architecture will make it easy to write applications: Application
developers will not have to understand low-level transaction and state management details,
multi-threading, connection pooling, or other complex low-level APIs.
4) Enterprise JavaBeans applications will follow the Write Once, Run Anywhere? philosophy of
the Java programming language. An enterprise bean can be developed once, and then
deployed on multiple platforms without recompilation or source code modi?cation.
5) The Enterprise JavaBeans architecture will address the development, deployment, and runtime
aspects of an enterprise application’s life cycle.
6) The Enterprise JavaBeans architecture will define the contracts that enable tools from multiple
vendors to develop and deploy components that can interoperate at runtime.
7)The Enterprise JavaBeans architecture will make it possible to build applications by combin-
ing components developed using tools from different vendors.
8) The Enterprise JavaBeans architecture will provide interoperability between enterprise beans
and Java 2 Platform, Enterprise Edition (J2EE) components as well as non-Java programming
language applications.
9) The Enterprise JavaBeans architecture will be compatible with existing server platforms. Ven-
dors will be able to extend their existing products to support Enterprise JavaBeans.
10) The Enterprise JavaBeans architecture will be compatible with other Java programming lan-
guage APIs.
11)The Enterprise JavaBeans architecture will be compatible with the CORBA protocols
從這些目標(biāo)中我們可以發(fā)現(xiàn),幾乎沒(méi)有目標(biāo)是針對(duì)開發(fā)人員效率的。從這次目標(biāo)中我們就可以隱約的感到EJB不是對(duì)開發(fā)者友好的技術(shù)。
從這些目標(biāo)中,我們可以發(fā)現(xiàn)EJB的雄心過(guò)于龐大,而EJB出現(xiàn)的時(shí)代,還不足以在一個(gè)規(guī)范中解決這些問(wèn)題。從EJB后來(lái)被人詬病最多的實(shí)體Bean,只是EJB的一小部分,但恰恰就這點(diǎn)就要了EJB的命。
EJB目標(biāo)中把本不應(yīng)該放在一起的東西給放在了一起,比如分布式和實(shí)體映射。而且錯(cuò)誤的假定了使用分布式的場(chǎng)合。按照Spring創(chuàng)始人的說(shuō)法
,分布式只有20%的應(yīng)用要用,而80%是不需要的。
我們現(xiàn)在知道EJB目標(biāo)不清楚,那我們免不了要問(wèn),當(dāng)初Sun為什么要這樣定位EJB?
也許除了EJB早期規(guī)范組的人,沒(méi)有人真正清楚為什么,我們此處只能留到以后事后諸葛亮下(注:此處我以后會(huì)用一片文章來(lái)分析產(chǎn)生的原因)。
二 編成模型復(fù)雜
EJB組成復(fù)雜:
一個(gè)EJB有好幾個(gè)東西組成,具體有主接口 ,遠(yuǎn)程/本地接口,Bean類,部署描述符
雖然開發(fā)社區(qū)發(fā)展了Xdoclet技術(shù),但也只是解決了一部分問(wèn)題。用Xdoclet,編譯時(shí)需要產(chǎn)生代碼,當(dāng)EJB多時(shí),這是很耗時(shí)的。
有過(guò)開發(fā)經(jīng)驗(yàn)的人都知道要是修改一個(gè)小東西需要修改幾個(gè)文件的話,那工作效率是上不去的,另外在考慮到EJB的需要部署,啟動(dòng)服務(wù)器的時(shí)間,修改EJB簡(jiǎn)直是痛苦啊。這樣必然導(dǎo)致開發(fā)周期長(zhǎng)。
編寫(定義接口, 實(shí)現(xiàn)Bean, 編寫部署描述符)-》打包部署-》 啟動(dòng)服務(wù)器-》測(cè)試。
早期開發(fā)中,我們還遵守規(guī)范中按角色編程的要求,導(dǎo)致角色多,溝通成本高,比如Bean開發(fā)者開發(fā)Bean,部署員打包部署,系統(tǒng)管理者管理服務(wù)器。
規(guī)范中說(shuō)的編寫一次,到處部署的承諾,基本是一句空話。結(jié)果變成了編寫一次,到處重寫。特別是實(shí)體Bean,基本上遷移一個(gè)服務(wù)器,就相當(dāng)于用HIbernate重新的工作量,還不考慮測(cè)試的困難性。規(guī)范中對(duì)實(shí)體映射定義的太過(guò)于寬泛,導(dǎo)致每個(gè)廠商都需要自己的ORM實(shí)現(xiàn),引入 特定廠商的部署描述符,又因?yàn)镴2EE中除web外,類加載的定義沒(méi)有明確,導(dǎo)致產(chǎn)生特定廠商的類加載機(jī)制和打包方式,還有就是特定廠商的服務(wù)查找方式。
四 部署描述符陷阱
1)EJB采用了當(dāng)時(shí)流行的使用Xml作為粘合劑,并且實(shí)現(xiàn)廠商都引入了自己的配置文件。結(jié)果導(dǎo)致編寫過(guò)多的配置文件。以JBoss為例要寫要寫三個(gè)配置文件。XML配置文件復(fù)雜,手工編寫比較困難,早期IDE中可視化編寫XML效率有不高,導(dǎo)致開發(fā)人員開發(fā)效率大大降低。更痛苦的是修改后,不能及時(shí)生效。大家想象一下,如果你有多個(gè)EJB,修改一個(gè)需要重新部署和啟動(dòng)服務(wù)器,那是怎樣的浪費(fèi)時(shí)間。以我曾經(jīng)的一個(gè)項(xiàng)目為例,約有100個(gè)EJB,部署和重啟JBoss需要幾分鐘,重要不是浪費(fèi)時(shí)間,而是那種挫折感。
2)標(biāo)準(zhǔn)的ejb-jar.xml部署描述符把一些重要的信息(比如指定EJB的JNDI名字和配置實(shí)例池)都留給容器提供商,
我們一般都需要一個(gè)額外,特定于容器的的部署描述符,比如weblogic-ejb-jar.xml。這樣導(dǎo)致編寫和移植的困難。
五 類加載陷阱(類加載器復(fù)雜,并且不清晰)
J2EE規(guī)范(Java EE)對(duì)EAR中web和ejb的加載沒(méi)有明確定義。比如一個(gè)EAR有多個(gè)EJB,每個(gè)EJB都依賴一些其他類庫(kù),那么對(duì)這些被依賴的類庫(kù)到底是怎么被加載的,類的可見(jiàn)性怎么樣,規(guī)范沒(méi)有規(guī)定。這樣每個(gè)廠商都有自己的一套東西,導(dǎo)致不同服務(wù)上,要用不同的打包方式。
六 測(cè)試?yán)щy
J2EE測(cè)試難是有目共睹的,其中EJB測(cè)試?yán)щy時(shí)出了名的。測(cè)試?yán)щy的原因時(shí),EJB運(yùn)行需要容器插入什么服務(wù),而啟動(dòng)服務(wù)器是很高昂的代價(jià)。
后來(lái)雖然開發(fā)社區(qū)采用Mock等技術(shù)試圖解決這個(gè)問(wèn)題,但從開發(fā)實(shí)踐來(lái)說(shuō),還是有難度的。
注: 以下幾點(diǎn)問(wèn)題,還需要詳細(xì)分析,由于時(shí)間問(wèn)題,暫時(shí)只是列出來(lái)。
七 破壞面向?qū)ο笤O(shè)計(jì)
八 開發(fā)周期長(zhǎng),部署慢
九 運(yùn)行時(shí)需要EJB容器,代價(jià)高
十 維護(hù)困難
但說(shuō)實(shí)話EJB也是有貢獻(xiàn),當(dāng)然它的貢獻(xiàn)更多是理念層次,在實(shí)現(xiàn)層面很失敗。另外,也正是他的失誤,在批判EJB的基礎(chǔ)上發(fā)展起Spring,給開發(fā)人員帶來(lái)一股新風(fēng)。