程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 精通J2EE應用程序開發之交叉分析J2EE

精通J2EE應用程序開發之交叉分析J2EE

編輯:關於JAVA

在不久前的一段時間內,Java 開發人員在准備一個新的企業 Java 開發項目時,事先就知道將要使用的工具。當時,一切都很簡單:J2EE 是新的,HTML 浏覽器是公認的用戶界面標准,而復雜性(至少從推測的角度而言)已成為過去的事情。而如今,事情變得如此復雜。

“開發人員面對的選擇令人眼花缭亂。”

開發人員面對的選擇令人眼花缭亂,從“輕型容器”(如 Spring、NanoContainer 或 HiveMind)到“web 框架”(如 WebWork、Tapestry(一個基於 JSF 的 UI,類似於 Oracle 的新應用程序開發框架 (Oracle ADF))或 Velocity)。這些選擇還增加了一系列新的 J2EE 規范,或者說是通過 JAXM、SAAJ、JAX-RPC 或 JAX 對“Web 服務”和相應的新技術術語“面向服務的體系結構”賦予了新的價值(更不用提“WS-*”規范、工具和庫了),Java 開發人員可以完成所有工作,這真是一個奇跡。

No Fluff Just Stuff 軟件論文系列的演講者 Ben Galbraith 將此現象稱作“Java 框架不確定性原則”:“您剛剛選擇了一個框架,某個其他框架的新版本便發布了,從而迫使您對選擇框架重新分析。”而且這種情況的復雜程度也無以復加了:只需將核心 J2EE 和 J2SE 類混合在一起使用。畢竟,我們被告知 EJB 是 J2EE 的“核心”,並且考慮一個沒有 EJB 的企業 Java 項目將是一個愚蠢的想法,這只是昨天的事。究竟泛型如何改變您的 J2EE 編碼體驗?並且到底是誰讓所有 Java 管理擴展成了路障?

到底是怎麼了?最初明確專注於創建一個由單項優勢工具和庫構成的平台的行業何以在如此短的時間內變得如此零亂?我們何時需要在傳統的“J2EE”工具(如 EJB)與新型“Web 服務”(如 JAXRPC 和 WS-Security)工具之間進行選擇?更重要的是,我們現在如何做才能避免 Ben 的 Java 框架不確定性原則而又不違背 Java 首先應遵循的供應商無關原則?

此問題主要在於了解最能滿足需要的技術,而最好的方法是首先了解應用程序的需要。了解應用程序的需要後,即可清楚地界定應選用的相應技術。

本文將簡要概述最先進的 J2EE、與其相關的技術以及 Java 開發人員當今面臨的某些體系結構挑戰。

我們如今要走向何處?

很多不同類型的 Java 程序在“企業 Java”的名義下趨於變得臃腫,在深入討論前,這也許有助於將它們與其他類型的 Java 應用程序區分開。如果我們從傳統的“3 層”方法開始(即將表示、業務邏輯和數據訪問劃分為三個一致的設計層次),則我們實際上可以確定五種“企業”Java 應用程序:煙囪、寶石、聚合器、集成器和企業應用程序。

“我們實際上可以確定五種“企業”Java 應用程序:煙囪、寶石、聚合器、集成器和企業應用程序”。

煙囪煙囪應用程序(也稱作“豎井”)可能是開發人員最容易接受的應用程序,這是因為它是一種我們一再開發的應用程序:它是傳統的“單數據庫、單 UI”應用程序,就絕對數量而言,它是當前構建最廣的一種 IT 應用程序。它通常是根據某個部門經理或副經理的需要(即尋找某個特定工具或應用程序來收集、操作和顯示某種當前未收集、操作和顯示的數據)而開始創建的,為此將組建一個團隊(規模通常不超過三到四個人,往往只有一個人)來收集需求、建立用例、構建數據庫、對業務邏輯進行編碼、將其部署到選擇作為此應用程序的生產服務器的機器並不斷地監視它。

當然,此名稱得自您在白板上繪制的三個框(表示系統的邏輯層 — 表示層、業務邏輯層和數據訪問層)所形成的圖像 — 它們構成了一條垂直線,不由使人想起將燃燒木頭的火爐中產生的煙排出到房間外面的舊式“煙囪”。(順便說一下,對於將該術語用作貶義術語的用戶而言,請記住,您在一生中將使用的許多最重要的系統(如 ATM 機、主要船運公司場地上的包裹定位器等)都是煙囪系統。

有一點可能比較令人吃驚的是,J2EE 軟件套件並不能完全滿足構建簡單煙囪系統的開發人員的需要。當只需要一個表示層,且只有一個資源用於存儲和檢索數據時,J2EE 套件(尤其是 EJB)就顯得“礙事”了。更誘人的方法是考慮輕型框架,因為它們並不那麼專注於部署描述符,並且就 JNDI、JMS 之類而言也沒什麼不便的。它只是通過 web 浏覽器進行的基本請求/響應通信,通常構建在類似 Struts 或相似的 MVC 樣式 web 框架中,並與一組核心的傳統 Java 對象(有時與單個機器上運行的表示層和業務邏輯層(而非數據庫本身))進行通信。(您可能奇怪此處為什麼沒有使用術語“數據庫”。原因很簡單,雖然大多數項目使用數據庫(而且還是關系數據庫)存儲數據,但數據存儲通常是原有系統、商業軟件程序包或形如 CICS 大型機、SAP 或 BizTalk 的“中介”技術。使用更一般的術語“資源”有助於強調這樣一個看法:後端實現確實與本討論無關。)

煙囪應用程序的另一個優勢是它們通常是“獨立的” — 也就是說不涉及其他應用程序。幾乎不需要遵守任何已建立的安全、可靠性或管理標准,這是因為此應用程序所確立的所有內容都將成為標准(至少對此應用程序而言是這樣,這正是此范圍的關鍵所在)。開發人員經常利用此事實來構建正好適合於此應用程序的基礎架構,從而消除了通常針對企業 Java 應用程序的指責:它們太復雜了,以至於無法使用和維護。

盡管人們希望如此,但 J2EE 的設計並非是針對煙囪應用程序的 — 當然,一個基於 J2EE 的應用程序可以構建此類應用程序(並且有上千個示例可以作為此事實的證據),事實上有點像用牛刀殺雞。基於 J2EE 的應用程序實施了一定程度的層劃分,但有時這種劃分對於解決手頭的問題顯得有些矯枉過正,如傳統的“10 用戶”煙囪系統。當然,問題是 10 用戶煙囪系統通常有一種另人不悅的趨勢,即轉變為其他四個版本中的某個版本,這樣將使事情變得很糟。就像某位哲學家說的那樣“沒有哪個人是孤立的”,我們也可以很輕松和准確地說“沒有哪個系統是孤立的”。至少在短期內是這樣。(當然,如果系統無法完成其預期的目標,那它就無法與任何其他系統集成,並且可能停產,但我們將假設那不是預期的目標。)

珠寶 我們並不是說這是 IT 環境的成功和驕傲或五種應用程序樣式中“最好”的一個,但珠寶樣式的應用程序是結合了多個表示層的應用程序(因此,它的名稱--“珠寶”表示有很多面可供查看)。但請注意,給定表示層可能根本不是供用戶查看的;公司當前經常探討的一個層是其基於 Web 服務的應用程序前端,它並非為人使用而設。盡管如此,該 Web 服務仍表示一個表示層,這是因為它從根本上執行同一操作:獲取輸入並從其下面的核心業務邏輯層中提供輸出。

由於一度曾存在的某些假設突然間不復存在了,珠寶應用程序對傳統編程模型進行了一些有趣的轉變。例如,當考慮一個 Web 服務前端時,突然必須以某種平台和語言無關的方式(對此,XML 模式是當前可以選擇的工具)定義類型,而理想情況下,“一次且僅此一次”規則(也稱作“不重復自身”原則)將允許我們直接通過基於 HTML 的表示層用來與業務邏輯層通信的同一類型構建此類型。這就是某些 JAX* 規范的用武之地--例如,Java API for XML Binding 有助於定義一個以非常模糊的方式進行“對象到 XML 以及 XML 到對象”轉換的標准方法,而 Java API for XML RPC (JAX-RPC) 定義一種使用 WSDL、SOAP 和 XML 構建可互操作的請求-響應遠程通信層的方法。

盡管任何事物都不能阻止開發人員從其最愛的輕型容器中使 JAX* 規范,而 J2EE 1.4 規范直接將 JAXRPC 和 JAXB 整合到它的總體技術套件中,從而使您可以將 EJB 無狀態會話 bean 提供為 WSL 1.1/SOAP 1.1 RPC/encoded Web 服務。(請注意,根據 WS-Interoperability Basic Profile 規范,RPC/編碼的服務正式不支持文檔/文字服務;人們普遍期望此差別在 JAX* 和 J2EE 規范的下個版本中得到解決,具體的實現應大概在開發人員實際指出RPC/編碼的服務和文檔/文字服務之間的差別時推出。)此外,商業應用服務器供應商正竭盡全力確保其產品不僅完全與 J2EE 標准兼容,而且還與 Web 服務標准兼容。顯而易見,這種情況下用“兼容且具競爭力”來形容供應商的動機(包括 J2EE 的主要競爭對手,來自西北太平洋的那家不知名的軟件公司的動機)再恰當不過。

順便說的是,打算構建 Web 服務表示 facet 時,值得一提的是,最好使用 JAXB 或 Oracle 的開發人員工具包將系統的模型對象直接提供為 XML 類型,並將整個 Web 服務前端代碼生成為大型 WSDL 文檔。盡管這起初似乎是某個用戶的業務邏輯層的良好驗證(畢竟,如果表示層中真的沒有什麼業務規則,那麼采用此方法其實並不困難),但 Web 服務技術套件中的限制很快便使這個期望變得很難實現。

例如,考慮基於引用的對象與 XML 的關系:應如何最佳地表示一個在 XML 中值為空的 java.util.Date 引用?尤其是在 .NET 中,Date 根本不是基於引用的對象,而是“值類型”,這意味著它的作用類似於 int 在 Java 中的作用嗎?當嘗試表示 XML 對象的復雜循環圖時,事情將變得非常棘手,這就是為什麼原來反對 RPC/編碼的服務的原因之一。這是 WS-* 套件背後所要做的所有工作,但即使某個團隊決定“走自己的路”並構建他們自己的 XML-over-HTTP 系統,他們也要面對同一核心問題。正在嘗試將對象-XML 映射整合到核心產品(如 Oracle Toplink)中,但到目前為止,它們仍處於初始階段。

同時,我們不能忽略那些旨在填補傳統的基於浏覽器應用程序中的大漏洞以實現“更大的響應性”的新潮表示層方法(“智能”客戶端或“富”客戶端”)。HTML 盡管有很多優點,但也存在一些根本性的缺點,很容易地就想到了兩個:

最小公分母角度。HTML 最初用於盡可能晚地推遲表示決策,標准 HTML 中實際上只有非常少的元素保證在任何給定系統上的呈現外觀。為頁面生成器提供更大控制(如 CSS)的嘗試已經取得了多方面的成功,尤其是在跨不同浏覽器方面。

表示代碼必須與內容一起發送。由於浏覽器本身不了解應用程序,因此必須在每個網絡往返中向服務器發送表示代碼和內容。此方法有兩個負面影響,一個是帶寬較低(每個客戶端的消耗越高,同一硬件的客戶端數越少),另一個是可用性遭到破壞(如果服務器或介入的任何拓撲出現故障,則應用程序將不存在)。

為實現此目的,企業應用程序供應商正積極考慮將表示層代碼置於最終用戶的機器中,以便完全或部分消除 HTML 的兩個主要缺點。這創造了一些有趣的部署暗示,但許多商店正尋求同時創建瘦客戶端和富客戶端表示層—富客戶端用於公司防火牆的內部,而瘦客戶端用於公司的外部(再次證明您不能太富或太瘦)。此方法招致了必須處理兩個不同框架的麻煩,但至少我們願意擁有一種將數據從用戶輸入傳遞到後端存儲庫的統一方法,而且最好能夠針對“富”客戶端和“瘦”客戶端將這種傳遞進行某種形式的標准化 — 由此便產生了 JSR 227,一個通用的數據綁定框架。

“我們願意擁有一個將數據從用戶輸入傳遞到後端存儲庫的統一方法;因此,便產生了 JSR 227。”

聚合器正如系統可以提供多個“入口點”一樣,如果您願意,系統還可以建立在多個後端的基礎上,從而從不同的資源收集數據並按一致和有意義的方式顯示它。(既然顯示和操作的數據是多個資源/數據庫的聚合,因此也就有了術語“聚合器”。)並且,在開始創建此聚合數據的操作和存儲用例的 30 秒之後,顯而易見的是,必須使用某種類型的原子性以便兩個數據庫所做的修改保持同步。這正是 Java 事務 API(以及它之前的 X/A 規范)的用途,而事務處理和業務邏輯的交叉部分則是 EJB 產生的原因。

但它不僅僅是事務。多個資源所帶來的不僅僅是兩個不同的數據庫 — 有時,系統需要的可靠性要高於單個數據庫機器所能提供的可靠性。畢竟,系統中任何位置的單個機器只表示單個故障點,而且通常情況下(除所有“熱交換”故障切換情況以外),我們只需關閉數據庫以對其執行某些預定的維護 — 可能包括新的模式更改以滿足代碼變換。Java 命名和目錄接口 (JNDI) 用作所有“查找”操作的單個 API,從實際底層物理數據庫機器中提供一個間接層,這意味著如果不緩存 JNDI 查找結果,則管理員可以更改 JNDI 入口,以從一台機器指向不同的機器,同時 J2EE 應用程序將簡單地進行相應的調整,從而將創建一個無縫和透明的指向新數據庫的“開關”,這在沒有間接層的情況下是無法實現的。

集成器

當需要連接兩個單獨維護的業務邏輯集合時,集成器系統將發揮作用,並且必須開始考慮煙囪系統從不需要的互操作性。例如,如果必須執行傳統的請求-響應服務,那麼如何執行請求和響應?開發人員通常立刻求助於 WS-* 服務,但如上所述,WS-* 規范有時太多(並且在當前實現中太不成熟),以至於無法可靠地滿足集成/互操作性的需要。而 J2EE 規范通過要求每個 EJB 容器符合 CORBA 調用(意味著任何 CORBA 客戶端可以與 EJB 容器中封裝的業務邏輯交互)再次滿足了此需要。

但並非所有集成均以請求-響應的方式進行。為避免 RPC 和請求-響應通信的異步本質中暗藏的瓶頸,許多系統選擇使用基於消息的方法相互集成。基於消息的方法是 Java 消息服務規范(以及關聯的實現,如 Oracle 的高級隊列)以及/或 Java API for XML Messaging (JAXM) 及其關聯的 SOAP API for Attachments in Java (SAAJ)(用於執行“使用尖括號的消息傳遞”)的用武之地。

數據庫本身還用作集成層,但與傳統 RPC 或消息驅動系統並不相同。很多情況下,集成和互操作性僅僅體現在將程序“A”中的數據傳遞到程序“B”,而數據庫(以及其他資源)通常用作不同平台(尤其是 J2EE 和 .NET)的有用(和理解充分)的中介語言。盡管它並不滿足所有互操作性的需要,但對於許多系統而言,此方法剛好滿足需要 — 它具有自身的好處,尤其是當業務邏輯(通過存儲過程)嵌入到數據庫中時。此外,.NET 無需了解如何調用駐留在 EJB 服務器中的 Java 代碼,Java 也無需了解如何調用駐留在 COM+ ServicedComponent 中的 .NET 代碼,或如何在兩者之間共享單個分布式事務 ID,等等。尤其是考慮到這樣一個事實:Oracle 允許您在 Java 而非 PL/SQL 中編寫存儲過程,從而簡化了存儲過程的編寫。

企業應用程序 最後,我們了解一下“真正的”企業應用程序,它是以下三個層的多個 facet 的融合:表示層、邏輯層和數據訪問層。傳統的企業系統需要使用遍布多個應用程序、語言或平台的業務規則集合以各種格式顯示多個資源中的數據。企業應用程序最具復雜性,而這正是 J2EE 的強項。此外,由於伴隨復雜性而來的是強大的功能(和靈活性),因此表面上“過於復雜的”J2EE 規范及其關聯技術變得更為合適。

例如,門戶通常就屬於此類別,這是因為它們通常需要在所有三個層實現多重性 — 對於表示層,體現在門戶通常組合了公司各個部分(或部門,或不同的公司,甚至可能是不同的移動家庭)的不同 web 應用程序,對於業務邏輯層,體現在特定“portlet”有時將需要調用由不同的 portlet 的後端提供的功能,對於數據訪問層,體現在大多數 portlet 擁有自身的用於交互的數據庫(或數據庫集,目的是使事物更有意義),但更有趣的是,給定用戶的會話通常需要跟蹤進程中的信息,即使用戶在各種 portlet 之間來回移動。在許多方面,門戶及其關聯 portlet 是企業應用程序的典范。

“在許多方面,門戶及其關聯 portlet 是企業應用程序的典范。”

它將我們至於何處?

此類分類本身就足夠出色了,因此會讓技術哲人們陶醉好一段時間,但這究竟與構建如今的企業 Java 應用程序有多大關系呢?

首先也是最重要的是,企業 Java 開發人員必須盡快確定他們被要求構建的應用程序屬於以上五種應用程序的哪一種。如果是傳統的煙囪系統,則選擇哪種技術並不像其他四個應用程序那樣重要。當出現 Web 服務問題時,將其看作是其他表示層(意味著您現在在查看珠寶應用程序)而不僅僅看作是 Struts 代碼與業務邏輯之間使用的模型對象擴展。實際上,在很多方面,模型視圖控制器模式是表示層本身的一部分,而並不是延伸到業務邏輯層的什麼東西,這是因為執行有效的“不同”表示層通常將要求我們針對如何與後端交互進行不同的選擇,如(對於 Web 服務)將系統的“面向對象”的本質拋在後面。

當出現多個數據庫或其他後端問題時,請考慮故障可分性和使用分布式事務實現可分性的需要,以及擁有一個良好的間接可熱交換層來訪問資源的故障切換建議。當現有系統之間的集成成為問題時,請記住除 Web 服務以外還有很多選擇(盡管 Web 服務方法比較實用並且通常被看作是標准),並記住消息驅動的系統以及是否可以將業務邏輯置於數據庫本身中以便其他需要與該系統交互的平台更容易地訪問此數據庫。

請記住,J2EE 只是用於實現某個目標的方法,對於任何技術的武斷看法通常將失去技術作為總體的意義。例如,不要試圖在煙囪系統上使用 EJB,這是因為 EJB 主要適用於事務處理(尤其是兩個階段的提交事務處理,此種事務處理比較占用資源並且必須在作為同一事務一部分的兩個或更多資源中獲取可分性),但當聚合器應用程序依靠您執行操作時不要忽略它的使用。當 JMS(和消息驅動 bean,當需要事務處理時)的異步本質更適合於此目的時,不要嘗試將所有內容編寫為會話 bean。等等。

其次,一定要始終確切地牢記應用程序的性能和可伸縮性目標(參見我的《高效企業 Java》一書)。盡管這對於以任何語言編寫的任何應用程序通常都很重要,但在企業 Java 領域中更重要,這是因為企業 Java 開發人員有那麼多的技術可以選擇。您的系統需要為每個用戶操作提供亞秒級響應?基於浏覽器的應用程序(尤其是跨廣域網應用程序)很難實現此目標,這是因為 HTML 浏覽器通常需要大約一秒的時間來處理甚至是中等復雜的 HTML 頁;或許一個更好的方法是考慮通過 JavaWebStart 提交的“富客戶端”前端,以便使跨網絡傳送的數據數量盡可能得小,以及接收數據的時間盡可能得短(以避免分析表示元素)。

是否需要在整個互聯網上擁有預測的 100 萬個用戶?用戶界面肯定需要改變,而 Java 在普通用戶的 PC 上的低普及率使 WebStart 並不切合實際,或許 applet 或傳統的 HTML 更為合適。但擴展到此用戶數目意味著開發人員需要特別留意在高峰負載下每個請求的響應時間,或許以不同的方式構建用戶界面可以避免頻繁的服務器回程。等等。

第三,請記住,Java 開發人員的工具套件在不斷的改進,過去五年中的大部分工作一直在朝 J2EE 領域的方向進行,想方設法使定義 J2EE 組件更簡單、更容易。大型商業供應商在該領域的優勢超過開源項目,這是因為供應商可以圍繞他們的商業服務創建完整的端到端開發經歷,其中開放源項目只是淺嘗辄止。例如,將 Oracle ADF 中提供的某些新功能與嘗試在 Eclipse 中構建 JSF 應用程序進行比較。或者,將在 JDeveloper 中定義 Web 服務與在 Axis 編寫 .wsdd 文件進行對比。工具越來越完善,我們只能期望此趨勢得以繼續,因為這要看供應商有沒有興趣使其繼續了。 “工具越來越完善,我們只能期望此趨勢得以繼續,因為這要看供應商有沒有興趣使其繼續了。”

最後但並非不重要的,在本系列的後續文章中留意此技術領域,這些後續文章將介紹從建模和設計到調試以優化/監視代碼(這將比您現在定義的性能和可伸縮性目標簡單很多)等主題。

最重要的是要放松。生命太短暫了。

結論

盡管企業 Java 領域有時像一組令人眼花缭亂的規范、實現,而實際上似乎迎合短暫流行風格的各種標准和框架已經做好充分的准備並意識到,對於五種類型的應用程序的任何一種而言,任何可用的 Java/J2EE 技術都可以工作(並出色地工作)。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved