JSF的加減法與Seam

梧桐雨—168發表於2008-05-15

  Jsf 本身是很多問題的。當然,jsf不是一項技術,而是標準。看看 javax.faces.* 包裡的內容,不是抽象類就是介面,是沒有實現的。 jsf 出來的時候目的也不是面向應用開發者的,而是面向元件供應商的,從這點意義上來說,jsf是成功的。Sun提供了一個reference implementation, 但是那更像是教元件供應商如何做元件的一個demo,而非真正意義上的給應用開發人員用的成型的元件。

  標準因為要融合各方需求,所以內容只能是各方能力的交集。至於標準之外的東西,則需要各方去發揮。

  JSF標準因為是先於成型的應用出來的(不同於EJB3的借鑑hibernate和spring,jsf299的借鑑seam),難免會有預見不足的地方。在某些地方可能作了過分的限制,而另外某些地方則完全沒有規定放得太開導致標準實現商完全忽略了它們。

  但是 Jsf 的初衷是不錯的,而且標準本身也足夠的可擴充套件。 所以現在才會誕生如此多的基於 jsf 的框架。 這些框架在不同程度上修復了 JSF 初始制定時的不足。

  Ajax4Jsf, Facelets, Seam 是這其中三個獨立的方向。

  1. A4J: 用網路檢測工具可以清晰地看到,每次在JSF postback 的時候,雖然可能只有部分頁面需要重新整理,但整個頁面都會被從伺服器送往瀏覽器。這是非常浪費的。 JSF的event-driven模型實際上非常適合部分頁面重新整理(試想如果沒有事件模型,每晃一下滑鼠顯示器就把整螢幕重畫,現在也就沒有 windows了),但是因為ajax出來的時候JSF標準已經final了,就沒有把Ajax考慮進去。對於事件模型來說,把整螢幕重畫改為部分元件重畫是件相對容易的事情,這也就是 Ajax4Jsf 這個專案的目的。是否開啟AJAX,可以不需要javascript,只是更改頁面中的某個開關(tag)就行了。

  2. Facelets: JSF是建立在JSP上的,但這是完全沒有必要的。JSP不是模板語言,它只是簡單得把嵌入在html裡的java語言原樣放入Java的原始檔裡,實際上是混合的html和java。這種模型和JSF的事件模型沒有任何互補的關係。相反,它給JSF加入了不必要的限制。Facelets的目的在於取代 jsp在jsf裡的地位。它是真正的模板語言,el表示式可以嵌入在頁面的任何位置,比如寫成:

  Hi,I'm Jordan, I think the winner of this cup isA4j Facelets, is that right?

  Facelets不需要編譯,頁面是hot-deploy的,效能比jsp快。另外,facelets本身提供了加參模板的功能,定製新的元件可以完全不寫java,只把頁面裡的需要提成元件的內容扔進分離的頁面,並且在taglib.xml裡面加入tag指向分離的頁面,並指定引數名字就可以了。 JSF最為人詬病的元件缺乏的問題,在facelets這裡得到了緩解,實際上是不怎麼需要第三方元件就可以快速寫出舒服的程式碼來。Facelets還有其它的功能,比如debug頁面顯示facelets頁面出錯的行號,比如無限巢狀的模板,等等。

  Seam 其實本身是無關JSF的,但是因為它從一開始就建在JSF上面,所以也不得不對JSF的一些問題進行修復。

  Seam的工作需要分開來細說:

  3.1 page行為 //TODO

  3.2 Context-filter //TODO

  3.3 RESTful(重建頁面引數) //TODO

  3.4 異常處理 //TODO

  3.5 跨越重定向的狀態 //TODO

  現在我們有了JSF的加減法:

  JSF - (全頁面重新整理) + Ajax4Jsf - Jsp + Facelets + 全域性Page行為 + Context-filter + Restful引數繫結 + 可定製異常 + 跨越重定向的狀態 = “ -_- ! 一大碗炸醬麵”

  就好像一件黃金聖衣,經過無數次修補,雖然還能再用,但是實在不如重鑄了。

  JSF 需要一套整合的模型,使這些各個分散的部分重新以一種整體的局面展現出來。它需要把多餘的東西拋棄掉,把新的內容以更整合的方式融在一起,因為光是熟悉這些不同分散的部分,理解它們之間的關係,知道哪裡會有BUG,哪裡則可以避免這些BUG,並且在運用的時候總是用對該用的東西,這已經使人非常頭大了。 JSF作為標準來說是成功的,在這一標準下有了如此多的可以插拔的第三方軟體。 但是該是時候對這些零散的東西統一了。就好像ubuntu在統一的指導思想下集合了儘可能多的零散的開源軟體,使它們可以被一種簡單並且相似的方式獲取,使我不需要像在Gentoo裡安裝任何一個東西都要搜尋搜尋再搜尋,瞭解它的來源,瞭解它的BUG,瞭解我的硬體是否支援。作為使用者,我不想學習,我想有明白的人替我作決定,那是最好的,特別是當這些決定make sense的時候。

  現在的Seam正是朝這個方向走的。能走這樣的路,得有兩個條件,一是有眾多零散的可用的東西,但是它們缺乏統一的形式(但它們得有能夠統一的背景,比如ubuntu下是posix標準,Seam下是jsf標準);二是有對該領域非常熟悉的人來做這樣的事情。上面提到的Seam對JSF的改進其實只是Seam框架下非常小的一部分,是Seam在向這個目標前進的必須的一個步驟,是在Seam核心基礎上水到渠成的東西,而遠非Seam的全部。正如Seam的名字所示:縫合;正如ubuntu的名字所示:分享與同在。它們的制定者在決定之初即是向著這一目標前進的。

  已經early draft review的JSR 299, 即是借鑑了Seam(以及其它比如Guice)的一個標準,試圖把這一方向推得更遠。

  至於對於縫合所需要的本事,Seam的conversation模型,CoC理念,元註解配置+xml補充方式,動態雙向注入模型(不同於spring的靜態單向注入),擴充套件了的EL等,是其基礎。內部事件和監聽模型,和drools的安全整合模型,和hibernate-seach, hibernate-validation, seam-remoting, jbpm,groovy,itext的整合,是其在基礎之上的應用。這些則需要另外的文章來寫了。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/13270562/viewspace-269159/,如需轉載,請註明出處,否則將追究法律責任。

相關文章