国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

利用EJB 3.0的JPA設計企業應用程序

2024-07-21 02:14:42
字體:
來源:轉載
供稿:網友
  本文將介紹 java platform, enterprise edition (java ee 5) 的一種設計方法,它利用了 enterprise javabeans (ejb) 3.0 新的 java persistence api (jpa)。jpa 提供了一種標準的對象關系映射解決方案,該解決方案避免了依賴第三方框架(如 hibernate)。您將看到示例應用程序的詳細內容,其中驗證了本方法并闡明關鍵設計決定。

  期待已久的下一版本 java ee 5 即將發布。java ee 5 許多新功能都包含經過修補的 ejb 架構,其突出特性之一是 jpa。由于具有容器內和容器外持久性選項,jpa 為 j2ee 架構師帶來一系列全新設計選擇。本文將著重介紹容器內應用程序的設計,此類應用程序依賴 ejb 容器提供企業服務,如事務處理和安全性。

  我將使用您熟悉的 petstore 應用程序進行測試,以證明 jpa 的功能以及它如何向傳統 j2ee 設計模式發起挑戰。本應用程序比較瑣碎,所以不提供詳盡的實現細節。我將用代碼摘錄對設計注意事項進行說明。本文假設您熟悉 ejb 3.0 基本概念和對象關系(or)映射基本概念。

  設計概述

  示例 petstore 應用程序是基于 web 的電子交易應用程序,它實現以下用例:
  • 瀏覽產品
  • 查找產品
  • 維護賬戶
  • 維護購物車
  • 創建訂單
  本應用程序被設計為具有三個主要邏輯層的多層 java ee 應用程序:
  • 表示層(并非本文的重點)使用 struts 框架。

  • 服務層是一種簡單的服務 facade,將所有工作委托給其協作者。服務層的目的是分離服務供應與服務實現。

  • 數據訪問層是一系列作為無狀態會話 bean 實現的粗粒度 data access objects (dao)。出于持久性的需要,它們都依賴 java 持久性實體管理器。
  應用程序域模型由 ejb 3.0 實體 bean 表示并用于層間的通信。當域對象離開數據訪問層時,它與實體管理器脫離。當重新進入數據訪問層時,它需要重新連接到實體管理器。

  注釋似乎是 java 5 的一個廣泛采用的特性,jpa 也不例外。注釋可用于指定 or 映射 —— 在 dw 文檔和教程中您經常可以看到 —— 而 petstore 應用程序出于相同目的使用它們。然而值得一提的是您還能通過映射文件的方式指定 or 映射。本文稍后的 or 映射 一節將探討并比較這兩種可選方式。

  我在 jboss 應用服務器中開發并部署 petstore 應用程序(參見 參考資料)。我使用商用數據庫完成大多數開發工作并將應用程序后端移植到 postgresql 數據庫(or 映射 一節包含了關于使用 jpa 時您應該了解的數據庫遷移的潛在影響的討論)。

  本案例分析的目的之一是符合設計標準,允許高度可測試的實現。如 測試 一節所見,您能夠使用一系列測試技術來測試 petstore 應用程序。

  petstore 應用程序充分利用了這一事實:它是規則的 web 應用程序。主要優點是所有層能夠運行在相同的 jvm 中,免除了組件分發的需要。本文的 遠程處理 一節簡要介紹了為應用程序添加遠程處理功能的方法。

  服務層

  服務層被設計為服務 facade。它由 petstoreservice 這一無狀態會話 bean 實現。bean 要完全依靠其協作者來提供 web 服務。

  因為簡化的 petstore 要求被限定于從數據庫檢索數據并把數據存儲于數據庫,惟一的協作者就是 dao。真正的應用程序能夠調用 web 服務,通過 rmi/iiop 或資源適配器訪問其他應用程序,并生成電子郵件消息等。所有此類型的功能都需要其他協作者支持。

  可通過 @ejb 或 @resource 注釋注入協作者(如清單 1 所示)或通過 @postconstruct 方法注入協作者(如清單 2 所示):

  清單 1. 使用 @ejb 注入協作者

 @ejb(beanname = "accountdao") accountdao accountdao;

  清單 2. 使用 @postconstruct 注入協作者

 messagesource messagesource; @postconstruct public void init() {    messagesource = new messagesourceimpl("exceptions"); } 

  選擇 bean 實現類的測試策略的主要因素是類完全依賴協作者來提供服務。這意味著類和協作者的交互作用需要被驗證。正如您在 測試 一節看到的,模仿對象方法完全滿足該目標。

  數據訪問層

  數據訪問層被設計為一系列粗粒度的 dao。dao 被實現為無狀態會話 bean,一個 bean 對應一個邏輯域:accountdao、orderdao 和 productdao。

  每個 bean 都要把實體管理器注入到其中:

 @persistencecontext(unitname = "manager1") protected entitymanager em; 

  這是應用程序中 持久性調用類(persistence-aware) 最多的層。它廣泛使用全新的 enterprise javabeans query language(ejb ql)。所有持久性相關的行動都在該層發生,例如:

 profile = (userprofile) em.createquery(    "from userprofile up where up.login = :login").setparameter(    "login", login).getsingleresult(); 

  下面是另一個例子:

 em.persist(account); 


  事實上這些類是持久性調用類(persistence-aware),需要一種容器內測試策略,這將在 測試 一節進行描述。

  域模型

  您可以把 jpa 看作是眾所周知的透明持久性技術(如 jdo 和 hibernate)的繼承者。盡管透明持久性可看作一個附加(add-on)服務,可被應用到忽略持久性的 plain old java objects (pojo)中,但 jpa 還是對域對象施加了少量限制。

  首先,您通常要具有一個映射到對應數據庫表主鍵的(代理)對象標識符:

@id @generatedvalue(strategy = generationtype.sequence, generator = "accountseq") @column(name = "account_sysid") public integer getaccountid() {    return this.accountid; } 

  其次,在聯機事務過程(oltp)環境中,需要一個 version 字段或 javabean 屬性以進行樂觀并發控制:

@column(name = "row_version") @version public int getversion() {    return version; } 

  最終,如果您選擇使用注釋方式的映射,映射注釋將分布在代碼周圍。
 
  另一種限制源自于這樣一個事實:域對象可以通過由實體管理器所管理的域對象所在的層訪問,也可以通過分離它的所有其他層訪問。此外,對象可能是新的或已刪除的。一般情況下,對象的行為取決于其持久性狀態。例如,假設在實體管理器中執行以下這行代碼:

 int size = attachedproduct.getitems().size(); 

  項集合使用給定產品的項填充,size 變量的值大于 0。如果使用默認懶加載(lazy)配置的一對多關聯,并在表示層中執行同一行代碼,size 變量的值為 0。 換句話說,在實體管理器之外(在實體管理器內也沒關系)無法把 非活動(lazy) 對象與 活動(eager) 對象區分開。解決此問題的方法是強制執行項目規范和約定。

  在域對象中,您可以把相同的推理應用到業務方法。無論是否在實體管理器中,它們都應該準備好在任何層中調用。這就是把域對象中的業務方法數量限制為必要的最少數量的理由。
  
  雖然有上述各種情況,域對象依然保留許多 pojo 特性。這意味著您可以使用 plain old java test (pojt) 對業務方法進行測試,pojt 這一術語引自 expert one-on-one j2ee development without ejb 一書。

  or 映射

  or 映射是圍繞 jpa 設計的應用程序的重要元素。它直接影響實體管理器填充域對象的方式。因此,變更映射能夠在表示層覺察到。變更獲取類型或級聯類型可能將產生非常不利的影響。

  正如前面所述,有兩種定義映射的方法:元數據(注釋)和映射文件。盡管我們高度提倡采用元數據的方法,但您應該也注意到了它所帶來的不便。從本質上講,此方法牽涉應用程序的兩個邏輯層:域模型和映射信息。因為這兩個層是分散的,所以這兩個層需要使用不同技術進行單獨測試。元數據方法本身不會影響層的可測試性。更確切的說,元數據方法使這兩個層好像只是一個層,由于受一系列因素的影響,這可能會引起問題。

  影響映射方法選擇的一個因素是項目小組結構。在只有少數開發人員參與的小型項目中,表的數量很少(一般說來少于 100 個表)而且沒有專職的映射人員,因為通常使用注釋會更加快速,所以把注釋方法看作定義映射也許是最佳選擇。對于擁有專職映射人員或映射小組的中型和大型項目來講,使用映射文件的方法才是更好的選擇。該方法可以降低資源爭用并使開發過程具有另一種自由度。基于元數據的映射方法證實是 petstore 應用程序更加節省時間的方法。

  or 映射層的目的是使其余應用程序免受底層數據庫變更的影響。當把 petstore 應用程序后端遷移到 postgresql 時,無需對映射層作出任何變更。這可能要歸結于這一事實:原始數據庫和 postgresql 這兩者均支持序列,因此主鍵生成策略保持完好。一般情況下,您應該對與對象 id 處理相關的映射區域進行重寫。

  對映射的全面測試覆蓋極為重要。必須覆蓋所有關系映射以確保對獲取行為和過渡持久性進行測試。您能夠利用容器外使用的 jpa 來執行該任務(將在下一節進行詳細介紹)。

  測試

  服務層設計的關鍵要素是,關注與底層的協作以提供請求的服務。這需要考慮到使用動態模仿對象的可靠測試策略。我使用 easymock 框架來實現測試方法。

  dao 層具有強大的數據庫內聚力。這就是可靠測試需要某類容器內策略和數據庫訪問的原因。盡管這對于遠程 ejb 很容易,還是需要考慮適合本地 bean 的有意義的方法。此處令人困擾的因素是:

  • 需要容器內測試 facade
  • 域對象是非連續的,所以全部驗證需要發生在容器內。


  jboss embeddable ejb3 容器(撰寫這篇文章時尚處于測試版階段)被證實是更適當的選擇。因為能夠從單元測試啟動 jboss embeddable ejb3 容器,這樣所有代碼都運行在同一 jvm 中。使用可嵌入容器的容器內測試可實現它的目標,但過程比較緩慢,因為容器啟動時間就需要大概 30 秒。這種問題可能是由較早的產品狀態造成的,可通過合理的配置改進。

  我采用 pojt 對域模型類的業務方法進行測試。不需要其他測試技術,況且其他測試技術不適合這些類。

  or 映射是一個需要窮舉測試覆蓋的主要層。該層對數據庫非常敏感,所以該層不能應用模仿對象或 pojt 技術。但是,您可以利用 jpa 的容器外功能。我就使用這種策略來測試 petstore 或 or 映射層。

  您需要牢記測試中的測試關聯和過渡持久性行為的重要性。這樣您才能及早注意到獲取類型的變更或級聯類型值的變更,并采取適當的措施。

  遠程處理

  petstore 應用程序設計的關鍵特性是它的本地特性。使應用程序的所有邏輯層運行在同一 jvm 中,這種方法具有很多優點。有關該主題的詳細討論,請參閱 expert one-on-one j2ee development without ejb

  不過,應當說明的是:通過遠程處理 facade,您可以輕松向應用程序添加遠程處理功能。遠程處理 facade(而不是我在前面描述的服務 facade)公開了一個遠程界面,它具有兩個職責:進行域模型和順序數據傳輸對象(dto)之間的相互轉換和在服務 facade 上調用適當的方法。

  使用遠程無狀態會話 bean 能夠實現本應用程序。唯一障礙是創建其他 dto 層和進行它們與域模型之間相互轉換。然而您需要它來確保實現整潔的界面以及與遠程客戶機的松散耦合。

  結束語

  ejb 3.0 和 jpa 毫無疑問將是 java ee 5 的主要賣點。在某些領域中,它們給正常的 java 社區帶來競爭優勢,并使 java 在其他領域與競爭對手不分伯仲。(不可否認的是,目前某些領域尚不存在基于標準的方法。)

  過去數年來,spring framework一直是 ejb 在企業領域的主要競爭對手。ejb 3.0 規范解決了很多促進 spring 興起的問題。隨著它的出現,ejb 3.0 毫無疑問比 spring 提供了更好的開發體驗 -- 最引人注目的優勢是它不需要配置文件。

  jpa 提供一種標準的 or 映射解決方案,該解決方案完全集成到 ejb 3.0 兼容的容器中。jpa 的前輩將會繼續穩定發展,但是業務應用程序中的 raw 使用將可能會減少。實現 jpa 兼容的實體管理器似乎很可能是此類技術的發展方向。

  在撰寫本文時,ejb 3.0 規范還處在建議的最終草案(proposed final draft)階段。以下是一些未解決的問題以及與 jpa 相關的預實現:

  • 當前形式的 jpa 規范沒有定義只讀實體 bean。這讓人困惑,因為兼容 ejb 2.1 規范的實體 bean 支持這種特性。spring 框架也支持只讀事務。

  • 可插入的持久性提供者概念仍處于未交付的階段。

  • 標準樂觀并發異常 -- optimisticlockexception -- 首次出現在 ejb 3.0 proposed final draft 中。在持久性提供者執行它以前 ,您還需要使用特定于提供者的異常,如 hibernate 的 staleobjectstateexception,來檢測樂觀并發問題。暫時,這種情況限制您的實現只能采用特定的持久性提供者。

  java ee 系列規范的較大問題與 jpa 沒有任何關系。java ee 系列規范的問題涉及到 web 和 ejb 容器之間的集成。spring 在此領域仍然具有主要競爭優勢。jboss 的 seam 項目嘗試使用自定義的方法來解決這一問題。caucho resin 應用服務器試圖擴展容器邊界并支持在 web 容器中使用 @ejb 注釋。我們希望 java ee 5.1 將解決層集成的問題,為我們提供一個全面而標準的依賴性注入方法。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 靖江市| 甘泉县| 龙门县| 崇文区| 宜川县| 雷州市| 大渡口区| 安化县| 谢通门县| 乳源| 垣曲县| 石家庄市| 邢台县| 佛山市| 台南县| 宜兰县| 自治县| 沐川县| 伊春市| 昭通市| 陈巴尔虎旗| 安仁县| 息烽县| 定州市| 安庆市| 泸州市| 龙里县| 奉节县| 武平县| 兴安盟| 台南县| 天峨县| 正镶白旗| 泸水县| 新安县| 内丘县| 崇州市| 祁阳县| 洪泽县| 南投县| 广东省|