衆所周知,在java EE5規範正式發佈之前,很多開源framework都非常出名,爲人們喜愛並廣泛使用,如Struts、Spring、Hibernate等,這些開放源代碼的作品曾經一定程度上成爲Java企業級應用開發事實上的標準。然而2006年5月,隨着Java EE 5規範的正式發佈,隨着衆多廠商對java EE5規範的衆多產品或者技術的支持的推出,開源與標準之間的競爭不可避免的......
Java EE 5的出現,可能是J2EE誕生以來比較重量級的一次震撼,規範發佈至今已有半年之多,業界對Java EE 5的關注也變得越來越熱烈,google一下“java ee”關鍵字,可以得到500多萬條相關紀錄,而從Sun網站上進行檢索(http://java.sun.com/javaee/overview/compatibility.jsp),也可以看到專業廠商已經迅速跟進,除Sun公司本身外,包括全球聞名的SAP、金蝶Apusic等另三家,已經推出全面支持Java EE 5規範的應用服務器產品。
Java EE 5包含JSF 1.2、EJB 3.0及JAX-WS 2.0等新功能,試圖解決Java企業級應用開發的簡便性、靈活性及易用性問題。在Java EE 5出現之前,很多開源框架(Open Source Framework)如雨後春筍般涌現,嘗試從某種角度或某些方面去解決“委員會”規範所未能顧及的應用開發問題,如Web開發中的關注分離問題(MVC)、業務模型實現問題(ORM)等等。很多開源framework都非常出名,爲人們喜愛並廣泛使用,如Struts、Spring、Hibernate等,這些“江湖派”作品曾經一定程度上成爲Java企業級應用開發事實上的標準。Java EE 5的出現,是否會改變這種狀況?或者說,人們在重新選擇應用框架時,是否會優先考慮全新的Java EE 5技術?帶着這種疑問,筆者試圖進行簡單的技術比較,並輔於膚淺的評論,希望能夠拋磚引玉、借花獻佛,以娛大衆。
Struts vs. JSF
|
Struts |
JSF |
MVC |
支持 |
支持 |
POJO |
|
支持 |
頁面流(Page Flow) |
支持 |
支持 |
UI組件(UI Component) |
|
支持 |
MVC是模型(Model)、視圖(View)、控制(Controller)分層的結構,通過分層來實現關注分離,減少傳統開發中常見並重復的工作。Struts和JSF均支持MVC。Struts對MVC支持的核心是Controller,通過Controller(一個共同的入口Servlet)獲得HTTP請求,將HTTP參數傳入ActionForm,然後將ActionForm傳給Action類。Struts對HTTP請求只有一個事件處理handler,當請求過來時,由相應Action返回結果給前端Controller,並據此選擇如何進行導航。JSF一般也採用一個前端Controller(有些商用JSF能夠智能識別JSF請求,無需額外的controller),不過在Controller中做的工作跟Struts Controller截然不同,它負責觸發JSF頁面組件中的事件,用Render工具生成組件的展現,綁定來自Model的數據到組件等。可以看到,JSF在在控制層更靈活,在視圖層支持Render工具的變換而生成靈活的展現,在模型層實現與框架的徹底分離,因而具有更高的靈活性。
POJO是無格式Java對象(Plain Old Java Object)。POJO與AOP結合被廣泛用於快速業務模型。Struts設計的初衷主要是解決視圖和控制問題,並無過多關注模型的靈活性問題。Struts中的ActionForm模型必須繼承自框架類,雖然可以通過定製類庫提供一些幫助類實現模型與框架無關,但本質上還是緊耦合於JSP- and HTTP-centric方法。JSF提供了對POJO天然的良好支持,並支持通過RAD工具實現快速的業務模型生成,從而具有更高的生產力。
頁面導航的最大意義是幫助實現頁面的可視化開發,在UI界面上快速定義頁面流向。頁面導航分靜態導航和動態導航兩種,靜態導航是頁面直接流向另一頁面,動態導航是由特定動作或邏輯決定頁面的流向。Struts和JSF均支持靜態和動態頁面導航。不過Struts中的導航規則是綁定到Action中的,那意味着可能需要對同一頁面中不同的Action做重複性的導航規則制定,而JSF導航可以跟Action無關,可以在頁面中不同組件的不同Action間共享相同的導航規則。
Struts本身並不提供UI組件機制,而JSF則提供了完整的UI組件機制。通過UI組件的定製和重用,能夠極大地簡化開發,提升用戶體驗。商業化的產品則往往更進一步,提供強大易用的開發工具,實現drag-and-drop方式所見即所得的Web UI開發。
Spring vs. EJB 3.0
|
Spring |
EJB3 |
標準(Standard) |
|
是,Java EE 5標準組成部分 |
持久(Persistence) |
JDBC, Hibernate, JDO, iBatis and JPA(ongoing spring 2.0) |
JPA |
聲明式服務(Declarative Services) |
支持 |
支持 |
依賴注入(Dependency Injection) |
支持 |
支持 |
集羣(Cluster) |
|
支持 |
Spring框架是一個開源項目,並不是一個標準的東西。Spring自己定義了一套XML配置文件大綱以及程序接口,從長遠考慮,有很大的不確定性。Spring的主要開發者來自Interface21公司(這是幫我非常敬重的人),Interface21靠相關諮詢和服務維持,作爲一個商業團體其利益取向將可以完全左右Spring未來的方向。相比EJB 3出身名門正派的標準血統並有衆多主流商業廠商支持,Spring的非標準性將可能帶來極大的風險。
Spring框架本身不帶持久實現,但它支持JDBC, Hibernate, JDO和 iBatis等持久化框架。Spring通過使用不同的DAO和Helper類以利用JDBC、Hibernate、iBatis或JDO,所以並沒有實現和最終服務提供者的隔離。簡單來說,就是需要重構代碼才能實現持久化框架的更換。EJB 3.0的持久集成在應用服務中,通過JPA,可以在底層更換持久實現,如將Hibernate更換爲Toplink。EJB 3.0的持久具有更大的靈活性,並有利於廠商進行性能優化和擴展。
Spring和EJB3.0都爲企業應用提供運行時服務,(如:事務、安全、日誌消息、配置服務)。由於這些服務都不是直接與應用的業務邏輯相關聯,所以都不是由應用來自行管理。EJB3.0使用Java註釋來配置聲明式服務,Spring使用XML配置文件。在大多數情況下,EJB3.0的註釋聲明顯得更爲簡單和優雅。Spring使用XML來定義屬性並配置聲明式服務的結果將是一個冗長而不穩定的配置文件。
依賴注入模式(DI)是在應用中實現鬆散耦合的最佳實踐。Spring和EJB3.0都支持DI模式,但他們有着深刻的不同。Spring支持通用的(但複雜的)基於XML配置文件的依賴注入API。EJB3.0支持注入大多數服務對象(如EJB和上下文對象)和通過簡單註釋聲明的JNDI對象。
EJB 3.0完全支持集羣。部署在服務集羣中的EJB3.0應用將自動獲得負載均衡、分佈緩存、狀態複製等功能。底層的集羣服務隱藏在EJB3.0編程接口後面,屏蔽了所有的複雜性。Spring沒有簡單的利用集羣的方法。
Hibernate vs. EJB 3.0
Hibernate與EJB 3.0其實並沒有很好的可比性,因Hibernate僅關注ORM,而EJB 3.0更多則更多表現爲一種組件框架,其中包含ORM部分而已。EJB 3.0在設計過程中,曾經得益於Hibernate的作者Gavin King,據說EJB 3.0 EntityBean的設計理念完全來自於Hibernate。只需用將EJB 3.0 EntityBean API調用轉換爲Hibernate API,Hibernate就可以成爲EJB 3.0中EntityBean的Implementation。
當開源framework已經成爲習慣性勢力,並給人們帶來衆多樂趣或疲憊感的時候,Java EE 5的出現會是適逢其時嗎?無論如何,是繼續選擇開源還是擁抱Java EE 5?相信今天這並不是個容易的選擇,或許,隨着更多的廠商發佈支持Java EE 5的產品,提供更好的工具支持,這個答案纔會明朗起來。