Java EE 5:強大的功能、高生產率和低複雜性

概述 Java EE 5 特性和提高開發人員生產率的改進

簡介

Java EE 技術是 Java 語言平臺的擴展,支持開發人員創建可伸縮的強大的可移植企業應用程序。它為應用程序組件定義了四種容器:Web、Enterprise JavaBean(EJB)、應用程序客戶機和 applet。一個應用服務器規範詳細描述了這些容器和它們必須支持的 Java API,這促使 Java EE 產品相互競爭,同時保證符合這個規範的應用程序可以在服務器之間移植(參見 Java EE 簡史)。

這個平臺的最新版本 Java EE 5 已經於 2006 年 5 月發佈。Java EE 5 主要關注提高開發人員的生產率,它提供了更簡單的編程模型,而沒有犧牲平臺的任何功能。更簡單的開發模型主要由兩個機制提供 —— Java 註解和更好的默認行為。主要的功能性改進包括改進了 Web 服務支持以及在平臺中集成了 JavaServer Faces(JSF)和 Java Standard Tag Library(JSTL)。

Java EE 簡史

Java EE 5 由 Java Community Process 通過 Java Specification Request 244 發佈,這個 “總綱” JSR 指出了詳細描述 Java EE 5 中各種技術的其他規範(參見 參考資料)。Sun Microsystems 的 Bill Shannon 領導一個專家組制訂了這個規範,這個專家組包括從 IT 行業重量級人物到個人專家的 31 位成員。以前的 Java EE 版本有:

  • J2EE 1.2(於 1999 年 12 月發佈):這是第一個 J2EE 版本,隨著 Java 2 Standard Edition(J2SE) 發佈。它包含 10 個規範和 API,針對企業應用程序所需的常用的 Web 層、業務邏輯、表示層和消息傳遞服務。
  • J2EE 1.3(於 2001 年 9 月發佈):通過 JSR 58 發佈,這個版本改進了半數 J2EE 1.2 規範並引入了 XML API、連接器架構和安全框架。
  • J2EE 1.4(於 2003 年 11 月發佈):這個版本改進了 J2EE 1.3 中 13 種技術中的 9 種,並引入了新的 Web 服務和安全支持。

J2EE 1.4 之後就是 Java EE 5,因為 Sun 已經從名稱中去掉了 “2”(這是從 Java 1.2 被稱為 “Java 2” 時開始的做法),而且現在在技術的簡寫名中使用單詞 “Java” 而不是 “J”。現在的標準版是 Java SE 6(而不是 J2SE 1.6),企業版是 Java EE 5(而不是 J2EE 1.5)。

本文介紹 Java EE 5 中的特性,重點介紹自上一個 J2EE 版本以來的變化。(超出本文範圍的改進包括 StAX API — 一個用來解析 XML 的 API — 和跨許多 API 的中小程度的改進。)我將全面討論四個特性類別:Web 服務、Web 應用程序、企業應用程序以及管理和安全性。然後,為了避免讀者覺得厭煩,我們討論一個使用 Java EE 5 特性的小應用程序,以此說明新的開發模型如何簡化面向服務架構(SOA) Web 應用程序的開發。

本文假設讀者熟悉企業級軟件系統,並希望全面瞭解 Java EE 5 的概況。瞭解 Java 編程和 J2EE 對於理解特性的意義會有幫助,但不是必需的。對示例應用程序的討論涉及一些技術細節,有 J2EE(至少是 Java 編程)背景可能比較容易理解。

Web 服務技術

在 Java EE 5 中引入了註解(annotation)特性,這簡化了複雜 Web 服務端點和客戶機的開發,與以前的 Java EE 版本相比,代碼更少,學習過程更短了。註解(最早在 Java SE 5 中引入)是可以作為元數據添加到代碼中的修飾性代碼。它們並不直接影響程序的語義,但是編譯器、開發工具和運行時庫可以通過處理它們生成額外的 Java 語言源文件、XML 文檔或其他工件和行為,這些對包含註解的程序起輔助作用(參見 參考資料)。在本文後面,會看到如何通過添加簡單的註解,將常規的 Java 類轉換為 Web 服務。

Web 服務支持方面的飛躍

Java EE 5 中 Web 服務支持的基礎是 JAX-WS 2.0,它是一種替代 JAX-RPC 1.1 的技術。這兩種技術都支持創建 REST 風格和基於 SOAP 的 Web 服務,而不必直接處理 Web 服務固有的 XML 處理和數據綁定細節。開發人員可以繼續使用 JAX-RPC(這仍然需要 Java EE 5 容器),但是強烈建議遷移到 JAX-WS。剛開始學習 Java Web 服務的開發人員可以跳過 JAX-RPC,直接使用 JAX-WS。它們都支持 SOAP 1.1 over HTTP 1.1,所以完全兼容:JAX-WS Web 服務客戶機可以訪問 JAX-RPC Web 服務端點,反之亦然。

與 JAX-RPC 相比,JAX-WS 有許多優點。JAX-WS:

  • 支持 SOAP 1.2 標準(以及 SOAP 1.1)。
  • 支持 XML over HTTP。如果願意,可以不使用 SOAP。(更多信息參見文章 “Use XML directly over HTTP for Web services (where appropriate)”。)
  • 使用 Java Architecture for XML Binding(JAXB)作為數據映射模型。JAXB 完全支持 XML 模式,而且性能更好(更多信息見下文)。
  • 為客戶機和服務器引入了一個動態編程模型。客戶機模型支持面向消息方式和異步方式。
  • 支持 Message Transmission Optimization Mechanism(MTOM),這是一個用於優化 SOAP 消息傳輸和格式的 W3C 建議規範。
  • 升級了 Web services interoperability(WS-I)支持。(它支持 Basic Profile 1.1;JAX-WS 只支持 Basic Profile 1.0。)
  • 升級了 SOAP 附件支持。(它支持 Attachments API for Java [SAAJ] 1.3:JAX-WS 只支持 SAAJ 1.2。)

通過閱讀文章 “Web 服務提示與技巧: JAX-RPC 與 JAX-WS 的比較”,可以進一步瞭解這些差異。

JAX-WS 中的 wsimport 工具自動地處理 Web 服務開發的許多細節,並以跨平臺方式集成到構建過程中,這讓開發人員可以將注意力集中於實現或使用服務的應用程序邏輯。它生成各種工件,包括服務、服務端點接口(SEI)、異步響應代碼、基於 WSDL 錯誤的異常以及通過 JAXB 綁定到模式類型的 Java 類。

JAX-WS 還能夠提高 Web 服務的性能。在文章 “Implementing High Performance Web Services Using JAX-WS 2.0”(參見 參考資料 中的鏈接)中,對基於 JAX-WS 的 Web 服務實現(使用了 Java EE 5 中的另外兩個 Web 服務特性 — JAXB 和 StAX)和基於 J2EE 1.4 中的 JAX-RPC 的服務實現做了性能對比。這項研究發現在不同負載下 JAX-WS 在各個功能領域產生了 40% 到 1000% 的性能改進。

Web 應用程序技術

除了現有的 JavaServer Pages 和 Servlet 規範,Java EE 5 引入了兩種前端技術 — JSF 和 JSTL。JSF 是一組 API,支持以基於組件的方式開發用戶界面。JSTL 是一組標記庫,支持在 JSP 中嵌入過程式邏輯、對 JavaBean 的訪問方法、SQL 命令、本地化格式指令和 XML 處理。JSF、JSTL 和 JSP 的最新版本支持一種統一表達式語言(expression language,EL),這使這些技術更容易集成在一起(參見 參考資料)。

JSF 1.2

JSF 為常見的 UI 問題提供了內置支持,比如組件狀態管理、事件處理、導航、用戶輸入檢驗和國際化。有經驗的開發人員可以創建定製的強大的可重用組件,還可以為 Web 瀏覽器之外的其他客戶機設備創建定製的組件。技術經驗不足的用戶可以在 Sun Java Studio Creator 等可視編程環境中重用定製組件,包括用於 HTML 界面的默認 JSF 標記庫。這讓編程新手也能夠創建複雜的 Web 表示層。

在開放源碼領域和受許可協議限制的軟件領域中,第三方 JSF 組件越來越多了。在 Web 上搜索 “JSF components” 或 “JSF component libraries” 會找到幾十種組件。許多組件都依賴於 Asynchronous JavaScript + XML(Ajax)技術,這種技術是 “Web 2.0” 運動背後的主要驅動力。Web 程序員可以使用它們創建出比傳統 Web 應用程序更好的用戶體驗,同時避免了從頭編寫 Ajax 組件的麻煩。

JSP 2.1

JSP 技術是從 J2EE 2.1 開始出現的。它使用 Java Servlet 規範支持聲明式的 UI 編程。它支持以文檔形式編寫 UI,Web 應用程序容器將這些文檔轉換為 Java servlet 並編譯,然後調用它們來響應請求。這些文檔通常將 JSP 指令和腳本片段與某種標記語言(比如 HTML)混在一起。JSP 可以使用老式語法(使用以 結束的特殊標記),也可以使用新的語法(良構的 XML)。它們通常作為 Model-View-Controller(MVC) UI 框架的 “View” 部分。

與以前的版本相比,JSP 2.1 和 JSF 1.2 之間的兼容性更好,這主要是因為它們的 EL 語法已經集成為統一 EL。EL 支持的操作包括:

  • 在請求、會話和應用程序上下文中訪問 JavaBean 的屬性。
  • 執行邏輯測試來做出各種選擇,比如隱藏還是顯示某個元素。
  • 通過計算生成在 UI 中顯示的數字和字符串。

過去,JSP 和 JSF EL 語法有差異,而且容器計算它們的方式也不一樣。統一 EL 消除了這些差異,還增加了一些特性,比如:

  • 一個可插入的框架,支持對 EL 的解釋進行定製。
  • 支持延期執行的表達式,JSP 標記處理器可以根據需要執行它們。
  • 支持賦值操作,例如可以在 JSP 代碼中用 EL 表達式設置 JavaBean 的屬性。

對於 JSP 標記庫開發人員來說,好消息是標記處理器現在支持用註解注入資源,所以大大簡化了執行 Java Naming and Directory Interface(JNDI)所需的資源配置和代碼。

JSTL 1.2

JSTL 已經存在多年了,但是在 Java EE 5 之前,Java EE 還不包含它。JSTL 標記支持在 JSP 中嵌入以下類型的元素:

  • 過程式邏輯,比如循環和 if/else 結構。
  • 對 JavaBean 的訪問方法,這可以向 UI 提供動態數據並允許 UI 代碼修改數據。
  • 執行數據庫訪問的 SQL 命令
  • 格式化指令,可以根據特定的地區對 UI 輸出進行格式化。
  • XML 處理,比如 Document Object Model(DOM)解析或 Extensible Stylesheet Language(XSL)轉換。

JSTL 1.2 是一個維護版本,它支持統一 EL 並解決了在同一個 JSP 頁面中混用 JSF 標記和 JSTL 迭代標記時遇到的問題。

Java Servlet 2.5

Java Servlet 規範是 Java Web 層技術的核心,它的歷史與 Java EE 技術本身一樣長。設計這個規範是為了提供一種高效率的基於組件的 Web 應用程序開發方法,並確保 Web 應用程序可以移植到實現這個規範的任何服務器上。

Java EE 5 所需的 Servlet 2.5 規範是一個維護版本,它對 2.4 版做了一些次要的改進。它在 Java 5 平臺上引入了一些依賴項,還引入了一些註解,它們可以減少對 Web 應用程序部署描述符配置文件(web.xml)的配置需求。還增加了一些方便的配置特性,例如可以用通配符和多個 url-pattern 元素更靈活地配置 servlet。

企業應用程序技術

有大量技術屬於企業應用程序的範圍,其中許多在 Java EE 5 中沒有變化或者不適合在本文中詳細討論。這裡主要關注兩個改進:對 EJB 開發的簡化和新的持久化特性。

EJB 3.0

EJB 規範是 Java EE 平臺的核心。它定義如何封裝應用程序的業務邏輯,並以高度可伸縮、可靠且感知事務的方式分佈業務邏輯,確保併發的數據訪問不會破壞數據。

EJB 有三種基本類型:

  • 會話 bean 分成兩類:無狀態有狀態。無狀態會話 bean 用於那些為單一客戶機請求提供服務的業務邏輯任務。有狀態會話 bean 維護客戶機的 “會話狀態”,適合處理那些跨越多個客戶機請求的任務。會話 bean 不能在客戶機之間共享。會話 bean 通常會操作一個或多個實體 bean。
  • 實體 bean 代表持久化數據,數據通常是從數據庫中裝載的。實體 bean 可以在客戶機之間共享,而且 EJB 規範提供了事務安全的機制,確保實體 bean 可以可靠地為多個併發客戶機請求提供服務,而不會被破壞。實體 bean 可以自己管理持久化,也可以讓容器來管理它(容器管理的持久化(container-managed persistence,CMP) )。
  • 消息驅動 bean(MDB) 用來處理那些不要求客戶機等待響應的客戶機請求。它們通常與一個 Java Message Service(JMS)隊列 — Java EE 5 中的另一種企業應用程序技術 — 進行交互,但是也可以以其他方式為異步客戶機提供服務,客戶機甚至可以不是用 Java 編寫的。

在過去,EJB 的開發很複雜很麻煩,開發人員常常不得不依靠工具來管理實現 EJB 所需的所有接口和部署描述符。規範為業務邏輯代碼規定了許多限制,要求擴展特定的類或實現特定的接口。為了獲得一個簡單的 EJB 引用,就需要許多樣板代碼。這些問題使 EJB 在開發社區中名聲很差;在許多情況中,EJB 確實很糟糕。

EJB 3.0 大大改進了 EJB 編程模型,這是提高 Java EE 5 開發人員生產率的主要因素之一。EJB 現在可以是一個加了註解的 “普通 Java 對象(plain old Java object,POJO)”,它不需要擴展特定的類。它只需要實現一個遠程接口,您可以自己定義這個接口,也可以讓 IDE 自動生成它。不再需要部署描述符了,因為 EJB 容器可以從 EJB 上的註解提取出所需的所有信息。

本文的 實踐:RideSynergy 應用程序 一節通過示例代碼給出這些改進的具體示例。如果需要了解更深入的細節,可以在 參考資料 中找到兩篇文章的鏈接,這兩篇文章提供了更有說服力的示例,說明了這個最新版本對 EJB 開發的改進是多麼顯著。

Java Persistence API(JPA 1.0)

JPA 引入了一個用於 Java 對象持久化的對象-關係映射(object-relational mapping,ORM)框架。在開發它時主要考慮 EJB 的需要,但是它可以用於任何 Java 對象。可以使用註解指定哪些對象和字段應該持久化,以及它們應該映射到哪些數據庫表和字段。JPA 支持一種與 SQL 相似的查詢語言。這種查詢語言可以:

  • 定義參數化的查詢,這種查詢可以以有序列表形式接收參數(按索引號引用參數),也可以採用按名稱引用的命名參數。
  • 按照持久化實體之間的關係執行查詢,而不需要 JOIN 語句(但是,如果您願意,也可以使用 JOIN 語句)。
  • 按照與 SQL 相似的方式指定搜索條件(比較操作符、LIKE 語句、BETWEEN 語句等等),定義如何對待結果集(使用 DISTINCT、ORDER BY、GROUP BY 等操作符)。

JPA 給 Java EE 平臺提供了新功能,解決了與手工持久化和容器持久化相關的許多麻煩。文章 “使用 EJB 3.0 Java Persistence API 設計企業應用程序” 提供了更多信息。

管理和安全性

Java EE 5 需要三個與以前版本相同的管理和安全性規範:

  • Application Deployment 提供一個用於將組件和應用程序部署到 Java EE 容器的 API。工具可以通過這個 API 將代碼部署到 Java EE 5 容器中,而不需要重新啟動容器。在開發期間,IDE 常常使用這個 API 支持快速的編寫/測試/糾正循環。
  • Application Management 為容器管理的對象指定必需的屬性和操作。它與多種行業標準管理協議兼容。
  • Authorization Contract for Containers(Java ACC)定義安全策略提供者的語義,以及如何授予對這個合約中的操作的訪問權。它要求容器實現一些接口,使部署工具能夠管理授權角色。

在 Java EE 5 中,這些規範都是維護版本(版本號都從 J2EE 1.4 中的 1.0 版升到 1.1 版),做了一些次要改進,這些超出了本文的範圍。更多信息參見 參考資料 中的 Java EE Management and Security Technologies 鏈接。

實踐:RideSynergy 應用程序

本節通過幾個示例展示 Java EE 5 中的簡化編程模型,說明這些模型如何提高開發人員的生產率。您可以看到如何通過這些模型快速開發一個示例應用程序,這個程序包含一個 Web 服務端點和客戶機,使用 EJB 實現業務邏輯,使用 JSF 作為 Web 前端。

WAS CE 2.0 上的 Java EE 5

WebSphere® Application Server, Community Edition(WAS CE)2.0 已經通過 Java EE 5 認證。瞭解關於 WAS CE 的更多信息並免費下載。

我將使用一個簡單的 Web 應用程序演示 Java EE 5 技術,這個程序是一個稱為 RideSynergy 的虛構的服務(下載 中提供了源代碼)。RideSynergy 服務幫助人們在網上安排合作用車。我使用 NetBeans 5.5 開發這個服務,並在 Sun Application Server 9.0_01 和 WebSphere Application Server(Community Edition)2.0 上測試過。

RideSynergy 的工作方式如下:

  • 它通過一個 Web 頁面接受車輛供應和請求。
  • 如果用戶提供車輛,它會顯示匹配的車輛請求列表。
  • 如果用戶請求車輛,它會顯示匹配的車輛供應列表。
  • 為了方便用戶,它會在顯示車輛供應和請求結果時顯示天氣預報,因為天氣可能影響用戶的決定。
  • 它以 Web 服務的形式向第三方應用程序提供關於供應和請求的統計數據。

訪問 RideSynergy 的用戶使用圖 1 所示的頁面提供或請求車輛,需要指定旅行起點和終點的 ZIP 編碼並輸入一個電子郵件地址。這個頁面還提供查看當地天氣報告的選項。

圖 1. RideSynergy 供應和請求頁面

Java EE 5:強大的功能、高生產率和低複雜性

如果提交一個車輛供應,結果頁面(見圖 2)會列出匹配的所有車輛請求。如果提交一個車輛請求,會列出匹配的供應。只有在供應和請求頁面上選擇 Check weather 複選框,才會顯示天氣預報(注意,在實際的應用程序中,顯示五天的天氣預報數據。為了簡單,圖 2 被截短了)。天氣預報數據是從一個公共 Web 服務(http://www.webservicex.net)獲得的。

圖 2. RideSynergy 結果頁面

Java EE 5:強大的功能、高生產率和低複雜性

RideSynergy 背後的代碼展示了 Java EE 5 的簡單 Web 服務編程模型:它使用 JAX-WS 建立一個 Web 服務端點定義(其中包含一個註解),並用 wsimport 特性創建一個 Web 服務客戶機。它還展示了 Java EE 5 中的簡單 EJB 編程模型和 JSF 的基本原理。

註解:用更少的代碼做更多工作

RideSynergy 以 Web 服務的形式提供統計數據,這個特性很好地說明了 Java EE 5 讓我們能夠用更少的代碼做更多工作。這個特性是在 RideStatistics 類中實現的,它演示了最簡單的 Java EE 5 註解形式。但是,簡單並不意味著功能不強:它們說明,與 J2EE 1.4 方式相比,用 Java EE 5 方式實現這些特性要簡單得多。

清單 1 中的 RideStatistics 類實現一個 Web 服務,它使用無狀態 RideManagerBean 會話 bean,根據 Web 服務客戶機指定的起點和終點 ZIP 編碼查詢匹配的車輛供應數量。RideManagerRemote 接口定義 RideManagerBean 上可供客戶機代碼使用的操作,客戶機代碼可以在同一個 JVM 中運行,也可以在其他 JVM 中運行。

清單 1. RideStatistics Web 服務

package com.ridesynergy;

import java.util.Set;
import javax.ejb.EJB;
import javax.jws.WebService;

/**

* Web Service that exposes a count of ride offers made to and from specific
* ZIP codes.
*
* @author smoore
*/
@WebService
public class RideStatistics {

@EJB
RideManagerRemote rideManager;

/** Creates a new instance of RideStatistics */
public RideStatistics() {
}

public Integer rideOffersFromZipCode(Integer zipCode) {
Set<ride> return new Integer(results.size());
}

public Integer rideOffersToZipCode(Integer zipCode) {
Set<ride> return new Integer(results.size());
}
}
/<ride>/<ride>

清單 1 包含兩個註解:@WebService 和 @EJB。首先,我要討論如何通過 @EJB 註解用依賴項注入(dependency injection) 技術訪問 EJB。然後討論如何通過 @WebService 註解將一個 POJO 變成完整的 Web 服務端點。

依賴項注入

如果您熟悉 J2EE 1.4 中的 EJB 編程,那麼在看到 清單 1 時可能會問:真的 這麼容易就獲得了一個 EJB 的引用嗎?是的,因為 @EJB 註解提供了一種基於依賴項注入的簡單編程模型。

有了 @EJB 註解,就不再需要編寫 J2EE 1.4 中的那些複雜代碼(比如清單 2 中的代碼):

清單 2. Java EE 5 之前的 RideManagerBean 客戶機

. . .
Context initial = new InitialContext();
Context myEnv = (Context) initial.lookup("java:comp/env");
Object obj = myEnv.lookup("ejb/RideManager");
RideManagerHome home = (RideManagerHome) PortableRemoteObject.narrow(
obj, RideManagerRemote.class);
RideManager manager = home.create();
. . .

在 Java EE 5 支持的 EJB 3.0 編程模型中,這個 @EJB 註解注入RideStatistics 對 RideManagerRemote的依賴項,這樣 RideStatistics 就不需要用 JNDI 查找引用。

它還避免了直接依賴於包含 RideManagerRemote 的包。看一下 import 語句;這裡沒有針對 RideManagerRemote 的 import 語句(但是,它卻可以通過編譯)。所以,可以將 RideManagerRemote重構到另一個包中,而不需要更新和重新編譯 RideStatistics。

註解還給依賴項的另一方面帶來許多好處:實際 EJB 提供 RideManagerRemote 背後的實現並告訴 Java EE 5 容器用它做什麼。我將稍後解釋。

複雜的運行時行為

當部署到 Java EE 5 容器時,JAX-WS 處理 清單 1 中的 @WebService 註解,並將 RideStatistics 類轉換為一個完整的 Web 服務端點,這個端點包含兩個操作:rideOffersFromZipCode 和 rideOffersFromToZipCode。JAX-WS 處理提供 Web 服務所需的所有工作,包括生成 Web Services Description Language(WSDL),讓 Web 上的其他應用程序能夠發現並使用這個 Web 服務,還提供機制響應對 Web 服務的客戶機請求。

JAX-WS 為 RideStatistics Web 服務生成 WSDL 的默認位置是 http://server:port/ridesynergy2-war/RideStatisticsService?WSDL。按照以下步驟查看這個 WSDL:

  1. 下載 RideSynergy 企業存檔文件 ridesynergy2.ear(見 下載)並將它部署到 Java EE 5 容器中。
  2. 將默認位置中的 serverport 值替換為容器的主機名和端口。
  3. 在瀏覽器中訪問這個位置。

更復雜的註解

清單 1 中的註解只是簡單的註解。註解還可以接受命名元素(named element),這種元素與方法參數相似,但是參數的次序和數量不重要,因為每個參數都有名稱。使用命名元素就像是將一個映射傳遞給註解,其中包含的鍵/值對可以決定處理註解的方式。

WeatherForecastSoap 接口(見清單 3)是由 JAX-WS 中的 wsimport 工具創建的,其中包含接受命名元素的註解。清單 3 給出 WeatherForecastSoap 接口:

清單 3. WeatherForecastSoap 接口

. . . 
@WebMethod(operationName = "GetWeatherByZipCode",
action = "http://www.webservicex.net/GetWeatherByZipCode")
public WeatherForecasts getWeatherByZipCode(
@WebParam(name = "ZipCode",
targetNamespace = "http://www.webservicex.net")
String zipCode);
. . .

在清單 3 中,getWeatherByZipCode() 方法上有一個 @WebMethod 註解,這個註解有兩個命名元素:operationName 和 action。getWeatherByZipCode() 的 zipCode 參數上有一個 @WebParam 註解,這個註解包含命名元素 name 和 targetNamespace(注意在實際應用程序中,getWeatherByZipCode() 還有其他註解,這裡省略掉了)。

定義註解的代碼指定註解接受哪些命名元素(如果有的話)。細節參見 參考資料 中的註解初級教程鏈接。

清單 4 給出 RideManagerBean 的類聲明,這個無狀態會話 bean 實現了 清單 1 所示的 RideManagerRemote 接口:

清單 4. 無狀態會話 bean 聲明

. . .
@Stateless
public class RideManagerBean implements RideManagerRemote {
. . .

在 J2EE 1.4 中,EJB 必須實現 SessionBean 接口,這個接口要求實現六個方法。在許多情況下,這些方法實現都是空的,它們之所以存在只是為了滿足接口的要求,讓代碼能夠通過編譯,這使代碼很雜亂。EJB 3.0 通過提供生命週期註解 @PostConstruct、@PreDestroy、@PostActivate 和 @PrePassivate 消除了這種混亂。可以根據需要將這些註解添加到適當的方法上,從而實現對生命週期事件的響應;只要求這些方法是公共方法,沒有參數並返回 void。

用註解替代部署描述符

Java EE 5 中的註解還可以消除以前的 Java EE 版本所需的大量配置代碼。例如,清單 4 中的 @Stateless 註解可以替代 EJB 部署描述符,EJB 部署描述符是一個 XML 配置文件,它向容器提供 EJB 的細節。在以前的 Java EE 平臺中,必須在一個符合 EJB 2.1 模式的 XML 文件中包含這樣的描述符。清單 5 給出配置 RideManagerBean 和所需接口的代碼片段:

清單 5. Java EE 5 以前的部署描述符

<display-name>RideManagerJAR/<display-name>
<enterprise-beans>
<session>
<ejb-name>RideManagerBean/<ejb-name>
<home>com.ridesynergy.RideManagerHome/<home>
<remote>com.ridesynergy.RideManager/<remote>
<ejb-class>com.ridesynergy.RideManagerBean/<ejb-class>
<session-type>Stateless/<session-type>
<transaction-type>Bean/<transaction-type>
<security-identity>
<use-caller-identity>
/<security-identity>
/<session>
/<enterprise-beans>

Java EE 5 向後兼容以前的 EJB 部署描述符。如果願意,甚至可以混合使用這兩種方式,讓遺留代碼用描述符指定 EJB,而用註解聲明新的 EJB。

除了減少所需的代碼量之外,註解還在維護方面有好處,因為配置信息就放在源代碼中,Sun 的架構師 Graham Hamilton 將這稱為 “truth-in-source-code”(參見 參考資料):對於正確地加上註解的類,不需要同時查看源代碼和配置文件,就能夠理解其運行方式,因為註解在源代碼中直接定義了特殊行為。

在 Roland Barcia 的文章 “瞭解 Java EE 5” 中,通過許多示例展示了 Java EE 5 中的註解如何簡化應用程序開發。

合理的默認行為

我們只添加了一個簡單的註解,就把 RideStatistics 變成了一個 Web 服務,這也展示了另一個 Java EE 5 設計原則:提供合理的默認行為,從而使編程模型更簡單。

在這個示例中,JAX-WS 假設在帶 @WebService 註解的類中所有公共方法都應該轉換為 Web 服務操作,並以方法名作為操作名。在處理這些方法的輸入參數和輸出參數時,也會做相似的假設。如果默認行為不適合您的需要,那麼可以通過在方法上加註解來修改。但是在許多情況下,都希望 Web 服務中使用的名稱與實現 Web 服務的類匹配,所以 JAX-WS 的默認行為是很合理的,這大大簡化了 Web 服務的開發。

結束語

在過去,Java EE 技術雖然很強大,但是也很麻煩;開發人員必須忍受它的複雜性,或者使用開發工具 “馴服” 它,才能享受到它的好處。這讓大家覺得使用 Java EE 非常累人,只有在大型的企業級平臺確實需要它的強大特性,而且組織擁有能夠應付 Java EE 開發的資源的情況下,才會考慮使用這種平臺。

Java EE 5 試圖消除這種壞名聲,使它成為適合企業應用程序開發的強大且易用的平臺,採取的措施包括提供註解等新的語言特性,採用合理的默認行為等設計目標,以及強調更簡單的編程模型。另外,更簡單的編程模型減少了不必要的複雜性,降低了開發人員對第三方工具的需求。因此,開發強大的企業應用程序的成本現在顯著降低了。開發人員花在與平臺 “搏鬥” 上的時間更少了,可以集中更多精力開發需要的實際功能,開發速度大大提高了。

以前被 Java EE 技術嚇退的開發團隊應該重新審視 Java EE 5,現有 J2EE 應用程序的開發人員和維護人員應該研究 Java EE 5 中的眾多特性,從而使自己的工作更輕鬆。

Java EE 5:強大的功能、高生產率和低複雜性


分享到:


相關文章: