隨著平臺的容器支持、開發(fā)人員工具、培訓(xùn)資源和開發(fā)人員社區(qū)體驗(yàn)等方面的改善,推動組織采用 Java? Platform, Enterprise Edition 5(Java EE 5)的動力正在穩(wěn)定增長。本文從較高層面介紹 Java EE 5 中新的生產(chǎn)率特性和 API 改進(jìn),并通過一個 Web 服務(wù)示例展示簡化的開發(fā)模型。
Java EE 技術(shù)是 Java 語言平臺的擴(kuò)展,支持開發(fā)人員創(chuàng)建可伸縮的強(qiáng)大的可移植企業(yè)應(yīng)用程序。它為應(yīng)用程序組件定義了四種容器:Web、Enterprise JavaBean(EJB)、應(yīng)用程序客戶機(jī)和 applet。一個應(yīng)用服務(wù)器規(guī)范詳細(xì)描述了這些容器和它們必須支持的 Java API,這促使 Java EE 產(chǎn)品相互競爭,同時(shí)保證符合這個規(guī)范的應(yīng)用程序可以在服務(wù)器之間移植(參見 Java EE 簡史 )。
這個平臺的最新版本 Java EE 5 已經(jīng)于 2006 年 5 月發(fā)布。Java EE 5 主要關(guān)注提高開發(fā)人員的生產(chǎn)率,它提供了更簡單的編程模型,而沒有犧牲平臺的任何功能。更簡單的開發(fā)模型主要由兩個機(jī)制提供 —— Java 注解和更好的默認(rèn)行為。主要的功能性改進(jìn)包括改進(jìn)了 Web 服務(wù)支持以及在平臺中集成了 JavaServer Faces(JSF)和 Java Standard Tag Library(JSTL)。
![]() |
|
本文介紹 Java EE 5 中的特性,重點(diǎn)介紹自上一個 J2EE 版本以來的變化。(超出本文范圍的改進(jìn)包括 StAX API — 一個用來解析 XML 的 API — 和跨許多 API 的中小程度的改進(jìn)。)我將全面討論四個特性類別:Web 服務(wù)、Web 應(yīng)用程序、企業(yè)應(yīng)用程序以及管理和安全性。然后,為了避免讀者覺得厭煩,我們討論一個使用 Java EE 5 特性的小應(yīng)用程序,以此說明新的開發(fā)模型如何簡化面向服務(wù)架構(gòu)(SOA) Web 應(yīng)用程序的開發(fā)。
本文假設(shè)讀者熟悉企業(yè)級軟件系統(tǒng),并希望全面了解 Java EE 5 的概況。了解 Java 編程和 J2EE 對于理解特性的意義會有幫助,但不是必需的。對示例應(yīng)用程序的討論涉及一些技術(shù)細(xì)節(jié),有 J2EE(至少是 Java 編程)背景可能比較容易理解。
在 Java EE 5 中引入了注解(annotation)特性,這簡化了復(fù)雜 Web 服務(wù)端點(diǎn)和客戶機(jī)的開發(fā),與以前的 Java EE 版本相比,代碼更少,學(xué)習(xí)過程更短了。注解(最早在 Java SE 5 中引入)是可以作為元數(shù)據(jù)添加到代碼中的修飾性代碼。它們并不直接影響程序的語義,但是編譯器、開發(fā)工具和運(yùn)行時(shí)庫可以通過處理它們生成額外的 Java 語言源文件、XML 文檔或其他工件和行為,這些對包含注解的程序起輔助作用(參見 參考資料 )。在本文后面,會看到如何通過添加簡單的注解,將常規(guī)的 Java 類轉(zhuǎn)換為 Web 服務(wù)。
Java EE 5 中 Web 服務(wù)支持的基礎(chǔ)是 JAX-WS 2.0,它是一種替代 JAX-RPC 1.1 的技術(shù)。這兩種技術(shù)都支持創(chuàng)建 REST 風(fēng)格和基于 SOAP 的 Web 服務(wù),而不必直接處理 Web 服務(wù)固有的 XML 處理和數(shù)據(jù)綁定細(xì)節(jié)。開發(fā)人員可以繼續(xù)使用 JAX-RPC(這仍然需要 Java EE 5 容器),但是強(qiáng)烈建議遷移到 JAX-WS。剛開始學(xué)習(xí) Java Web 服務(wù)的開發(fā)人員可以跳過 JAX-RPC,直接使用 JAX-WS。它們都支持 SOAP 1.1 over HTTP 1.1,所以完全兼容:JAX-WS Web 服務(wù)客戶機(jī)可以訪問 JAX-RPC Web 服務(wù)端點(diǎn),反之亦然。
與 JAX-RPC 相比,JAX-WS 有許多優(yōu)點(diǎn)。JAX-WS:
-
支持 SOAP 1.2 標(biāo)準(zhǔn)(以及 SOAP 1.1)。
-
支持 XML over HTTP。如果愿意,可以不使用 SOAP。(更多信息參見文章 “
Use XML directly over HTTP for Web services (where appropriate)
”。)
-
使用 Java Architecture for XML Binding(JAXB)作為數(shù)據(jù)映射模型。JAXB 完全支持 XML 模式,而且性能更好(更多信息見下文)。
-
為客戶機(jī)和服務(wù)器引入了一個動態(tài)編程模型。客戶機(jī)模型支持面向消息方式和異步方式。
-
支持 Message Transmission Optimization Mechanism(MTOM),這是一個用于優(yōu)化 SOAP 消息傳輸和格式的 W3C 建議規(guī)范。
-
升級了 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 服務(wù)提示與技巧: JAX-RPC 與 JAX-WS 的比較 ”,可以進(jìn)一步了解這些差異。
JAX-WS 中的
wsimport
工具自動地處理 Web 服務(wù)開發(fā)的許多細(xì)節(jié),并以跨平臺方式集成到構(gòu)建過程中,這讓開發(fā)人員可以將注意力集中于實(shí)現(xiàn)或使用服務(wù)的應(yīng)用程序邏輯。它生成各種工件,包括服務(wù)、服務(wù)端點(diǎn)接口(SEI)、異步響應(yīng)代碼、基于 WSDL 錯誤的異常以及通過 JAXB 綁定到模式類型的 Java 類。
JAX-WS 還能夠提高 Web 服務(wù)的性能。在文章 “Implementing High Performance Web Services Using JAX-WS 2.0”(參見 參考資料 中的鏈接)中,對基于 JAX-WS 的 Web 服務(wù)實(shí)現(xiàn)(使用了 Java EE 5 中的另外兩個 Web 服務(wù)特性 — JAXB 和 StAX)和基于 J2EE 1.4 中的 JAX-RPC 的服務(wù)實(shí)現(xiàn)做了性能對比。這項(xiàng)研究發(fā)現(xiàn)在不同負(fù)載下 JAX-WS 在各個功能領(lǐng)域產(chǎn)生了 40% 到 1000% 的性能改進(jìn)。
?
除了現(xiàn)有的 JavaServer Pages 和 Servlet 規(guī)范,Java EE 5 引入了兩種前端技術(shù) — JSF 和 JSTL。JSF 是一組 API,支持以基于組件的方式開發(fā)用戶界面。JSTL 是一組標(biāo)記庫,支持在 JSP 中嵌入過程式邏輯、對 JavaBean 的訪問方法、SQL 命令、本地化格式指令和 XML 處理。JSF、JSTL 和 JSP 的最新版本支持一種統(tǒng)一表達(dá)式語言(expression language,EL),這使這些技術(shù)更容易集成在一起(參見 參考資料 )。
JSF 為常見的 UI 問題提供了內(nèi)置支持,比如組件狀態(tài)管理、事件處理、導(dǎo)航、用戶輸入檢驗(yàn)和國際化。有經(jīng)驗(yàn)的開發(fā)人員可以創(chuàng)建定制的強(qiáng)大的可重用組件,還可以為 Web 瀏覽器之外的其他客戶機(jī)設(shè)備創(chuàng)建定制的組件。技術(shù)經(jīng)驗(yàn)不足的用戶可以在 Sun Java Studio Creator 等可視編程環(huán)境中重用定制組件,包括用于 HTML 界面的默認(rèn) JSF 標(biāo)記庫。這讓編程新手也能夠創(chuàng)建復(fù)雜的 Web 表示層。
在開放源碼領(lǐng)域和受許可協(xié)議限制的軟件領(lǐng)域中,第三方 JSF 組件越來越多了。在 Web 上搜索 “JSF components” 或 “JSF component libraries” 會找到幾十種組件。許多組件都依賴于 Asynchronous JavaScript + XML(Ajax)技術(shù),這種技術(shù)是 “Web 2.0” 運(yùn)動背后的主要驅(qū)動力。Web 程序員可以使用它們創(chuàng)建出比傳統(tǒng) Web 應(yīng)用程序更好的用戶體驗(yàn),同時(shí)避免了從頭編寫 Ajax 組件的麻煩。
JSP 技術(shù)是從 J2EE 2.1 開始出現(xiàn)的。它使用 Java Servlet 規(guī)范支持聲明式的 UI 編程。它支持以文檔形式編寫 UI,Web 應(yīng)用程序容器將這些文檔轉(zhuǎn)換為 Java servlet 并編譯,然后調(diào)用它們來響應(yīng)請求。這些文檔通常將 JSP 指令和腳本片段與某種標(biāo)記語言(比如 HTML)混在一起。JSP 可以使用老式語法(使用以
<%
開頭、以
%>
結(jié)束的特殊標(biāo)記),也可以使用新的語法(良構(gòu)的 XML)。它們通常作為 Model-View-Controller(MVC) UI 框架的 “View” 部分。
與以前的版本相比,JSP 2.1 和 JSF 1.2 之間的兼容性更好,這主要是因?yàn)樗鼈兊?EL 語法已經(jīng)集成為統(tǒng)一 EL。EL 支持的操作包括:
- 在請求、會話和應(yīng)用程序上下文中訪問 JavaBean 的屬性。
- 執(zhí)行邏輯測試來做出各種選擇,比如隱藏還是顯示某個元素。
- 通過計(jì)算生成在 UI 中顯示的數(shù)字和字符串。
過去,JSP 和 JSF EL 語法有差異,而且容器計(jì)算它們的方式也不一樣。統(tǒng)一 EL 消除了這些差異,還增加了一些特性,比如:
- 一個可插入的框架,支持對 EL 的解釋進(jìn)行定制。
- 支持延期執(zhí)行的表達(dá)式,JSP 標(biāo)記處理器可以根據(jù)需要執(zhí)行它們。
- 支持賦值操作,例如可以在 JSP 代碼中用 EL 表達(dá)式設(shè)置 JavaBean 的屬性。
對于 JSP 標(biāo)記庫開發(fā)人員來說,好消息是標(biāo)記處理器現(xiàn)在支持用注解注入資源,所以大大簡化了執(zhí)行 Java Naming and Directory Interface(JNDI)所需的資源配置和代碼。
JSTL 已經(jīng)存在多年了,但是在 Java EE 5 之前,Java EE 還不包含它。JSTL 標(biāo)記支持在 JSP 中嵌入以下類型的元素:
-
過程式邏輯
,比如循環(huán)和
if
/else
結(jié)構(gòu)。
-
對 JavaBean 的訪問方法
,這可以向 UI 提供動態(tài)數(shù)據(jù)并允許 UI 代碼修改數(shù)據(jù)。
-
執(zhí)行數(shù)據(jù)庫訪問的
SQL 命令
。
-
格式化指令
,可以根據(jù)特定的地區(qū)對 UI 輸出進(jìn)行格式化。
- XML 處理 ,比如 Document Object Model(DOM)解析或 Extensible Stylesheet Language(XSL)轉(zhuǎn)換。
JSTL 1.2 是一個維護(hù)版本,它支持統(tǒng)一 EL 并解決了在同一個 JSP 頁面中混用 JSF 標(biāo)記和 JSTL 迭代標(biāo)記時(shí)遇到的問題。
Java Servlet 規(guī)范是 Java Web 層技術(shù)的核心,它的歷史與 Java EE 技術(shù)本身一樣長。設(shè)計(jì)這個規(guī)范是為了提供一種高效率的基于組件的 Web 應(yīng)用程序開發(fā)方法,并確保 Web 應(yīng)用程序可以移植到實(shí)現(xiàn)這個規(guī)范的任何服務(wù)器上。
Java EE 5 所需的 Servlet 2.5 規(guī)范是一個維護(hù)版本,它對 2.4 版做了一些次要的改進(jìn)。它在 Java 5 平臺上引入了一些依賴項(xiàng),還引入了一些注解,它們可以減少對 Web 應(yīng)用程序部署描述符配置文件(web.xml)的配置需求。還增加了一些方便的配置特性,例如可以用通配符和多個
url-pattern
元素更靈活地配置 servlet。
?
有大量技術(shù)屬于企業(yè)應(yīng)用程序的范圍,其中許多在 Java EE 5 中沒有變化或者不適合在本文中詳細(xì)討論。這里主要關(guān)注兩個改進(jìn):對 EJB 開發(fā)的簡化和新的持久化特性。
EJB 規(guī)范是 Java EE 平臺的核心。它定義如何封裝應(yīng)用程序的業(yè)務(wù)邏輯,并以高度可伸縮、可靠且感知事務(wù)的方式分布業(yè)務(wù)邏輯,確保并發(fā)的數(shù)據(jù)訪問不會破壞數(shù)據(jù)。
EJB 有三種基本類型:
-
會話 bean
分成兩類:
無狀態(tài)
和
有狀態(tài)
。無狀態(tài)會話 bean 用于那些為單一客戶機(jī)請求提供服務(wù)的業(yè)務(wù)邏輯任務(wù)。有狀態(tài)會話 bean 維護(hù)客戶機(jī)的 “會話狀態(tài)”,適合處理那些跨越多個客戶機(jī)請求的任務(wù)。會話 bean 不能在客戶機(jī)之間共享。會話 bean 通常會操作一個或多個實(shí)體 bean。
-
實(shí)體 bean
代表持久化數(shù)據(jù),數(shù)據(jù)通常是從數(shù)據(jù)庫中裝載的。實(shí)體 bean 可以在客戶機(jī)之間共享,而且 EJB 規(guī)范提供了事務(wù)安全的機(jī)制,確保實(shí)體 bean 可以可靠地為多個并發(fā)客戶機(jī)請求提供服務(wù),而不會被破壞。實(shí)體 bean 可以自己管理持久化,也可以讓容器來管理它(
容器管理的持久化(container-managed persistence,CMP)
)。
- 消息驅(qū)動 bean(MDB) 用來處理那些不要求客戶機(jī)等待響應(yīng)的客戶機(jī)請求。它們通常與一個 Java Message Service(JMS)隊(duì)列 — Java EE 5 中的另一種企業(yè)應(yīng)用程序技術(shù) — 進(jìn)行交互,但是也可以以其他方式為異步客戶機(jī)提供服務(wù),客戶機(jī)甚至可以不是用 Java 編寫的。
在過去,EJB 的開發(fā)很復(fù)雜很麻煩,開發(fā)人員常常不得不依靠工具來管理實(shí)現(xiàn) EJB 所需的所有接口和部署描述符。規(guī)范為業(yè)務(wù)邏輯代碼規(guī)定了許多限制,要求擴(kuò)展特定的類或?qū)崿F(xiàn)特定的接口。為了獲得一個簡單的 EJB 引用,就需要許多樣板代碼。這些問題使 EJB 在開發(fā)社區(qū)中名聲很差;在許多情況中,EJB 確實(shí)很糟糕。
EJB 3.0 大大改進(jìn)了 EJB 編程模型,這是提高 Java EE 5 開發(fā)人員生產(chǎn)率的主要因素之一。EJB 現(xiàn)在可以是一個加了注解的 “普通 Java 對象(plain old Java object,POJO)”,它不需要擴(kuò)展特定的類。它只需要實(shí)現(xiàn)一個遠(yuǎn)程接口,您可以自己定義這個接口,也可以讓 IDE 自動生成它。不再需要部署描述符了,因?yàn)?EJB 容器可以從 EJB 上的注解提取出所需的所有信息。
本文的 實(shí)踐:RideSynergy 應(yīng)用程序 一節(jié)通過示例代碼給出這些改進(jìn)的具體示例。如果需要了解更深入的細(xì)節(jié),可以在 參考資料 中找到兩篇文章的鏈接,這兩篇文章提供了更有說服力的示例,說明了這個最新版本對 EJB 開發(fā)的改進(jìn)是多么顯著。
JPA 引入了一個用于 Java 對象持久化的對象-關(guān)系映射(object-relational mapping,ORM)框架。在開發(fā)它時(shí)主要考慮 EJB 的需要,但是它可以用于任何 Java 對象。可以使用注解指定哪些對象和字段應(yīng)該持久化,以及它們應(yīng)該映射到哪些數(shù)據(jù)庫表和字段。JPA 支持一種與 SQL 相似的查詢語言。這種查詢語言可以:
-
定義參數(shù)化的查詢,這種查詢可以以有序列表形式接收參數(shù)(按索引號引用參數(shù)),也可以采用按名稱引用的命名參數(shù)。
-
按照持久化實(shí)體之間的關(guān)系執(zhí)行查詢,而不需要
JOIN
語句(但是,如果您愿意,也可以使用JOIN
語句)。
-
按照與 SQL 相似的方式指定搜索條件(比較操作符、
LIKE
語句、BETWEEN
語句等等),定義如何對待結(jié)果集(使用DISTINCT
、ORDER BY
、GROUP BY
等操作符)。
JPA 給 Java EE 平臺提供了新功能,解決了與手工持久化和容器持久化相關(guān)的許多麻煩。文章 “ 使用 EJB 3.0 Java Persistence API 設(shè)計(jì)企業(yè)應(yīng)用程序 ” 提供了更多信息。
?
Java EE 5 需要三個與以前版本相同的管理和安全性規(guī)范:
-
Application Deployment
提供一個用于將組件和應(yīng)用程序部署到 Java EE 容器的 API。工具可以通過這個 API 將代碼部署到 Java EE 5 容器中,而不需要重新啟動容器。在開發(fā)期間,IDE 常常使用這個 API 支持快速的編寫/測試/糾正循環(huán)。
-
Application Management
為容器管理的對象指定必需的屬性和操作。它與多種行業(yè)標(biāo)準(zhǔn)管理協(xié)議兼容。
- Authorization Contract for Containers (Java ACC)定義安全策略提供者的語義,以及如何授予對這個合約中的操作的訪問權(quán)。它要求容器實(shí)現(xiàn)一些接口,使部署工具能夠管理授權(quán)角色。
在 Java EE 5 中,這些規(guī)范都是維護(hù)版本(版本號都從 J2EE 1.4 中的 1.0 版升到 1.1 版),做了一些次要改進(jìn),這些超出了本文的范圍。更多信息參見 參考資料 中的 Java EE Management and Security Technologies 鏈接。
?
實(shí)踐:RideSynergy 應(yīng)用程序
本節(jié)通過幾個示例展示 Java EE 5 中的簡化編程模型,說明這些模型如何提高開發(fā)人員的生產(chǎn)率。您可以看到如何通過這些模型快速開發(fā)一個示例應(yīng)用程序,這個程序包含一個 Web 服務(wù)端點(diǎn)和客戶機(jī),使用 EJB 實(shí)現(xiàn)業(yè)務(wù)邏輯,使用 JSF 作為 Web 前端。
![]() |
|
我將使用一個簡單的 Web 應(yīng)用程序演示 Java EE 5 技術(shù),這個程序是一個稱為 RideSynergy 的虛構(gòu)的服務(wù)( 下載 中提供了源代碼)。RideSynergy 服務(wù)幫助人們在網(wǎng)上安排合作用車。我使用 NetBeans 5.5 開發(fā)這個服務(wù),并在 Sun Application Server 9.0_01 和 WebSphere Application Server(Community Edition)2.0 上測試過。
RideSynergy 的工作方式如下:
-
它通過一個 Web 頁面接受車輛供應(yīng)和請求。
-
如果用戶提供車輛,它會顯示匹配的車輛請求列表。
-
如果用戶請求車輛,它會顯示匹配的車輛供應(yīng)列表。
-
為了方便用戶,它會在顯示車輛供應(yīng)和請求結(jié)果時(shí)顯示天氣預(yù)報(bào),因?yàn)樘鞖饪赡苡绊懹脩舻臎Q定。
- 它以 Web 服務(wù)的形式向第三方應(yīng)用程序提供關(guān)于供應(yīng)和請求的統(tǒng)計(jì)數(shù)據(jù)。
訪問 RideSynergy 的用戶使用圖 1 所示的頁面提供或請求車輛,需要指定旅行起點(diǎn)和終點(diǎn)的 ZIP 編碼并輸入一個電子郵件地址。這個頁面還提供查看當(dāng)?shù)靥鞖鈭?bào)告的選項(xiàng)。
圖 1. RideSynergy 供應(yīng)和請求頁面
?
如果提交一個車輛供應(yīng),結(jié)果頁面(見圖 2)會列出匹配的所有車輛請求。如果提交一個車輛請求,會列出匹配的供應(yīng)。只有在供應(yīng)和請求頁面上選擇 Check weather 復(fù)選框,才會顯示天氣預(yù)報(bào)(注意,在實(shí)際的應(yīng)用程序中,顯示五天的天氣預(yù)報(bào)數(shù)據(jù)。為了簡單,圖 2 被截短了)。天氣預(yù)報(bào)數(shù)據(jù)是從一個公共 Web 服務(wù)(http://www.webservicex.net)獲得的。
RideSynergy 背后的代碼展示了 Java EE 5 的簡單 Web 服務(wù)編程模型:它使用 JAX-WS 建立一個 Web 服務(wù)端點(diǎn)定義(其中包含一個注解),并用
wsimport
特性創(chuàng)建一個 Web 服務(wù)客戶機(jī)。它還展示了 Java EE 5 中的簡單 EJB 編程模型和 JSF 的基本原理。
RideSynergy 以 Web 服務(wù)的形式提供統(tǒng)計(jì)數(shù)據(jù),這個特性很好地說明了 Java EE 5 讓我們能夠用更少的代碼做更多工作。這個特性是在
RideStatistics
類中實(shí)現(xiàn)的,它演示了最簡單的 Java EE 5 注解形式。但是,簡單并不意味著功能不強(qiáng):它們說明,與 J2EE 1.4 方式相比,用 Java EE 5 方式實(shí)現(xiàn)這些特性要簡單得多。
清單 1 中的
RideStatistics
類實(shí)現(xiàn)一個 Web 服務(wù),它使用無狀態(tài)
RideManagerBean
會話 bean,根據(jù) Web 服務(wù)客戶機(jī)指定的起點(diǎn)和終點(diǎn) ZIP 編碼查詢匹配的車輛供應(yīng)數(shù)量。
RideManagerRemote
接口定義
RideManagerBean
上可供客戶機(jī)代碼使用的操作,客戶機(jī)代碼可以在同一個 JVM 中運(yùn)行,也可以在其他 JVM 中運(yùn)行。
清單 1. RideStatistics Web 服務(wù)
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< results = rideManager.findCloseOfferMatches(zipCode, 0); return new Integer(results.size()); } public Integer rideOffersToZipCode(Integer zipCode) { Set<Ride< results = rideManager.findCloseOfferMatches(0, zipCode); return new Integer(results.size()); } }
?
清單 1 包含兩個注解:
@WebService
和
@EJB
。首先,我要討論如何通過
@EJB
注解用
依賴項(xiàng)注入(dependency injection)
技術(shù)訪問 EJB。然后討論如何通過
@WebService
注解將一個 POJO 變成完整的 Web 服務(wù)端點(diǎn)。
如果您熟悉 J2EE 1.4 中的 EJB 編程,那么在看到
清單 1
時(shí)可能會問:
真的
這么容易就獲得了一個 EJB 的引用嗎?是的,因?yàn)?
@EJB
注解提供了一種基于依賴項(xiàng)注入的簡單編程模型。
有了
@EJB
注解,就不再需要編寫 J2EE 1.4 中的那些復(fù)雜代碼(比如清單 2 中的代碼):
清單 2. Java EE 5 之前的 RideManagerBean 客戶機(jī)
. . . 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
的依賴項(xiàng),這樣
RideStatistics
就不需要用 JNDI 查找引用。
它還避免了直接依賴于包含
RideManagerRemote
的包。看一下
import
語句;這里沒有針對
RideManagerRemote
的
import
語句(但是,它卻可以通過編譯)。所以,可以將
RideManagerRemote
重構(gòu)到另一個包中,而不需要更新和重新編譯
RideStatistics
。
注解還給依賴項(xiàng)的另一方面帶來許多好處:實(shí)際 EJB 提供
RideManagerRemote
背后的實(shí)現(xiàn)并告訴 Java EE 5 容器用它做什么。我將稍后解釋。
當(dāng)部署到 Java EE 5 容器時(shí),JAX-WS 處理
清單 1
中的
@WebService
注解,并將
RideStatistics
類轉(zhuǎn)換為一個完整的 Web 服務(wù)端點(diǎn),這個端點(diǎn)包含兩個操作:
rideOffersFromZipCode
和
rideOffersFromToZipCode
。JAX-WS 處理提供 Web 服務(wù)所需的所有工作,包括生成 Web Services Description Language(WSDL),讓 Web 上的其他應(yīng)用程序能夠發(fā)現(xiàn)并使用這個 Web 服務(wù),還提供機(jī)制響應(yīng)對 Web 服務(wù)的客戶機(jī)請求。
JAX-WS 為 RideStatistics Web 服務(wù)生成 WSDL 的默認(rèn)位置是 http:// server : port /ridesynergy2-war/RideStatisticsService?WSDL。按照以下步驟查看這個 WSDL:
- 下載 RideSynergy 企業(yè)存檔文件 ridesynergy2.ear(見 下載 )并將它部署到 Java EE 5 容器中。
- 將默認(rèn)位置中的 server 和 port 值替換為容器的主機(jī)名和端口。
- 在瀏覽器中訪問這個位置。
清單 1 中的注解只是簡單的注解。注解還可以接受 命名元素(named element) ,這種元素與方法參數(shù)相似,但是參數(shù)的次序和數(shù)量不重要,因?yàn)槊總€參數(shù)都有名稱。使用命名元素就像是將一個映射傳遞給注解,其中包含的鍵/值對可以決定處理注解的方式。
WeatherForecastSoap
接口(見清單 3)是由 JAX-WS 中的
wsimport
工具創(chuàng)建的,其中包含接受命名元素的注解。清單 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
參數(shù)上有一個
@WebParam
注解,這個注解包含命名元素
name
和
targetNamespace
(注意在實(shí)際應(yīng)用程序中,
getWeatherByZipCode()
還有其他注解,這里省略掉了)。
定義注解的代碼指定注解接受哪些命名元素(如果有的話)。細(xì)節(jié)參見 參考資料 中的注解初級教程鏈接。
清單 4 給出
RideManagerBean
的類聲明,這個無狀態(tài)會話 bean 實(shí)現(xiàn)了
清單 1
所示的
RideManagerRemote
接口:
. . . @Stateless public class RideManagerBean implements RideManagerRemote { . . .
?
在 J2EE 1.4 中,EJB 必須實(shí)現(xiàn)
SessionBean
接口,這個接口要求實(shí)現(xiàn)六個方法。在許多情況下,這些方法實(shí)現(xiàn)都是空的,它們之所以存在只是為了滿足接口的要求,讓代碼能夠通過編譯,這使代碼很雜亂。EJB 3.0 通過提供生命周期注解
@PostConstruct
、
@PreDestroy
、
@PostActivate
和
@PrePassivate
消除了這種混亂。可以根據(jù)需要將這些注解添加到適當(dāng)?shù)姆椒ㄉ希瑥亩鴮?shí)現(xiàn)對生命周期事件的響應(yīng);只要求這些方法是公共方法,沒有參數(shù)并返回
void
。
Java EE 5 中的注解還可以消除以前的 Java EE 版本所需的大量配置代碼。例如,
清單 4
中的
@Stateless
注解可以替代 EJB 部署描述符,EJB 部署描述符是一個 XML 配置文件,它向容器提供 EJB 的細(xì)節(jié)。在以前的 Java EE 平臺中,必須在一個符合 EJB 2.1 模式的 XML 文件中包含這樣的描述符。清單 5 給出配置
RideManagerBean
和所需接口的代碼片段:
<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。
除了減少所需的代碼量之外,注解還在維護(hù)方面有好處,因?yàn)榕渲眯畔⒕头旁谠创a中,Sun 的架構(gòu)師 Graham Hamilton 將這稱為 “truth-in-source-code”(參見 參考資料 ):對于正確地加上注解的類,不需要同時(shí)查看源代碼和配置文件,就能夠理解其運(yùn)行方式,因?yàn)樽⒔庠谠创a中直接定義了特殊行為。
在 Roland Barcia 的文章 “ 了解 Java EE 5 ” 中,通過許多示例展示了 Java EE 5 中的注解如何簡化應(yīng)用程序開發(fā)。
我們只添加了一個簡單的注解,就把
RideStatistics
變成了一個 Web 服務(wù),這也展示了另一個 Java EE 5 設(shè)計(jì)原則:提供合理的默認(rèn)行為,從而使編程模型更簡單。
在這個示例中,JAX-WS 假設(shè)在帶
@WebService
注解的類中所有公共方法都應(yīng)該轉(zhuǎn)換為 Web 服務(wù)操作,并以方法名作為操作名。在處理這些方法的輸入?yún)?shù)和輸出參數(shù)時(shí),也會做相似的假設(shè)。如果默認(rèn)行為不適合您的需要,那么可以通過在方法上加注解來修改。但是在許多情況下,都希望 Web 服務(wù)中使用的名稱與實(shí)現(xiàn) Web 服務(wù)的類匹配,所以 JAX-WS 的默認(rèn)行為是很合理的,這大大簡化了 Web 服務(wù)的開發(fā)。
在過去,Java EE 技術(shù)雖然很強(qiáng)大,但是也很麻煩;開發(fā)人員必須忍受它的復(fù)雜性,或者使用開發(fā)工具 “馴服” 它,才能享受到它的好處。這讓大家覺得使用 Java EE 非常累人,只有在大型的企業(yè)級平臺確實(shí)需要它的強(qiáng)大特性,而且組織擁有能夠應(yīng)付 Java EE 開發(fā)的資源的情況下,才會考慮使用這種平臺。
Java EE 5 試圖消除這種壞名聲,使它成為適合企業(yè)應(yīng)用程序開發(fā)的強(qiáng)大且易用的平臺,采取的措施包括提供注解等新的語言特性,采用合理的默認(rèn)行為等設(shè)計(jì)目標(biāo),以及強(qiáng)調(diào)更簡單的編程模型。另外,更簡單的編程模型減少了不必要的復(fù)雜性,降低了開發(fā)人員對第三方工具的需求。因此,開發(fā)強(qiáng)大的企業(yè)應(yīng)用程序的成本現(xiàn)在顯著降低了。開發(fā)人員花在與平臺 “搏斗” 上的時(shí)間更少了,可以集中更多精力開發(fā)需要的實(shí)際功能,開發(fā)速度大大提高了。
以前被 Java EE 技術(shù)嚇退的開發(fā)團(tuán)隊(duì)?wèi)?yīng)該重新審視 Java EE 5,現(xiàn)有 J2EE 應(yīng)用程序的開發(fā)人員和維護(hù)人員應(yīng)該研究 Java EE 5 中的眾多特性,從而使自己的工作更輕松。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
