程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Enterprise JavaBeans組件慨述之二

Enterprise JavaBeans組件慨述之二

編輯:關於JAVA

EJB 編程模型

本文的第二部分說明創建 Enterprise JavaBean 組件所需的 Java 接口和類的作用。除了對 bean 類本身進行編碼外,EJB 開發人員還必須為 bean 定義一個本地接口和一個遠程接口。這些接口的實現類通常由容器生成,因此部署 EJB 組件是開發人員和 EJB 容器的合作行為。第二部分還區分了 enterprise bean 的兩種主要類型,即會話 bean 和實體 bean,並說明了 EJB 容器和 EJB 服務器之間的關系。

enterprise bean 的編程模型的三個關鍵特征是:面向對象、對象的分布式和使用代理對象。由於此編程模型使用 Java 技術,因此它在本質上就是面向對象的。此模型也是分布式的,這是指 bean 在理論上是位置透明的。根據 Enterprise JavaBeans (EJB) 規范,“一般說來,EJB 類和 EJB 容器的實際位置對客戶機是透明的。”在客戶機想要訪問 EJB 組件時使用代理對象。bean 本身對於客戶機是不可訪問的,對 bean 方法的訪問則由 helper 類提供。

接口、委托和代理

當 Java 程序員編寫一個 Enterprise JavaBeans 組件時,他們所創建的類必須實現一個 EJB 接口,並且它必須包含一個名為 ejbCreate() 的方法。一個 EJB 接口 -- 例如 SessionBean 接口 -- 指定了一些方法,它們包括以下各項:

ejbActivate()

ejbPassivate()

ejbRemove()

setSessionContext()

ejbActivate() 和 ejbPassivate() 方法通知一個 bean,管理該 bean 的容器組件正在主動和被動之間切換 bean 的狀態(這通常是指在內存中還是交換到磁盤)。ejbRemove() 方法使 bean 知道它已被從容器中刪除。setSessionContext() 方法使 bean 與一個上下文對象相關聯,此上下文對象是為了便於 bean 與其容器進行通信。

ejbCreate() 方法並不是從零做起創建 enterprise bean 的。當客戶機想要創建新的 enterprise bean 時,bean 的容器將調用這個 bean 的類的 newInstance() 方法,來實例化新的 bean 對象。然後容器調用 setSessionContext() 方法來建立上下文對象,用於與 bean 進行通信。最後,容器調用新 bean 中的 ejbCreate() 方法。像 ejbCreate()、ejbActivate() 和 ejbPassivate() 這樣的方法有時稱為對象生存周期方法,以區別於業務邏輯方法。

當開發人員設計一個新的 EJB 組件時,編寫組成 enterprise bean 類的代碼本身是不夠的。EJB 程序員還必須編寫兩個將由 helper 類使用的 Java 接口。這些強制性接口必須擴展標准的 EJBObject 和 EJBHome 接口,而這兩個接口則都是 java.rmi.Remote marker 接口的擴展。擴展標准 EJBObject 接口的接口被稱為 enterprise bean 的遠程接口,它指定在 bean 自身中定義的業務方法。當應用程序調用 enterprise bean 中的業務方法時,應用程序並不訪問 bean 本身。實際上,方法調用被傳遞給實現 EJBObject 接口擴展的那個對象。這種做法稱為委托,它是 EJB 體系結構中的一個設計要點:

“客戶機從來不直接訪問 enterprise bean 類的實例。客戶機總是使用 enterprise bean 的遠程接口來訪問 enterprise bean 的實例。實現 enterprise bean 的遠程接口的類由容器提供。此類所實現的分布式對象稱為 EJB 對象。”(Enterprise JavaBeans Specification 1.0)

bean 對 EJBObject 接口的擴展稱為其遠程接口,而實現遠程接口的對象則稱為 EJB 對象。

enterprise bean 還必須具有本地接口。此接口是標准 EJBHome 接口的擴展。實現 bean 的本地接口的對象稱為本地對象。本地對象包含一個 create() 方法,此方法由應用程序調用,而應用程序則必須創建一個 bean 實例。本地對象中的 create() 方法創建一個新的 EJB 對象。它並不直接創建新的 enterprise bean 實例,因為不允許直接訪問 bean。

EJB 對象和本地對象充當 bean 對象的代理,因為它們代表 bean 接收方法調用。EJB 對象主要為 bean 業務方法充當代理;本地對象主要為 bean 生存周期方法充當代理。

為 EJB 組件使用 create() 方法並不一定要實例化新的 bean。容器確定如何最好地滿足創建請求,對於某些類型的 bean,它可以重用現有的實例:

“客戶機使用會話 bean 本地接口上的 create 和 remove 方法。雖然客戶機以為它正在控制著 EJB 實例的生存周期,但是,是容器在處理 create 和 remove 調用,而不一定要創建和刪除 EJB 實例。在客戶機和...實例之間不存在固定的映射。容器只是將客戶機的工作委托給任何一個方法已經就緒的可用實例而已。”(Enterprise JavaBeans Specification 1.0)

創建新的 bean 實例受容器的控制,並可以與客戶機發布 create() 方法異步。

當創建一個 EJB 組件時,開發人員負責定義 EJBObject 接口和 EJBHome 接口,但是無需編寫實現這些接口的類的代碼。EJB 容器軟件組件自動創建這些類。

下面的代碼段說明客戶機應用程序可能怎樣使用稱為 CartBean 的 enterprise bean 來進行在線購物:

CartHome cartHome = javax.rmi.PortableRemoteObject.narrow(
initialContext.lookup("applications/shopping_cart"), CartHome.class);
Cart cart = cartHome.create();
cart.addItem(item29);
cart.addItem(item67);
cart.addItem(item91);
cart.purchase();
cart.remove();

CartHome 是實現本地接口的類(EJBHome 接口的擴展)。Cart 是實現遠程接口的類(EJBObject 接口的擴展)。當客戶機調用應用程序方法(如 addItem() 和 purchase())時,它們是在 cart 對象上調用的,此對象接著將這些方法的執行委托給 bean 自身。enterprise bean 的功能是通過其代理 EJB 對象(即 cart)來獲得的。如果多台客戶機同時訪問 cart bean,將會發生什麼事情呢?Enterprise bean 開發人員無需編寫代碼來支持並發訪問。並發性由 EJB 容器支持。

下圖說明各 EJB 對象之間的關系:

服務器和容器

EJB 體系結構包括 EJB 服務器和 EJB 容器兩個概念。EJB 服務器充當一種組件執行系統,正如 EJB 白皮書中所述:

“Enterprise JavaBeans 規范為每個支持完全可移植性的 Java 應用程序服務器定義了一個標准模型。任何廠商都可以使用此模型來實現對 Enterprise JavaBeans 組件的支持。多種系統(如 TP 監視器、CORBA 運行時系統、COM 運行時系統、數據庫系統、Web 服務器系統或其它基於服務器的運行時系統)都可以調整到能夠支持可移植的 Enterprise JavaBeans 組件。”(Thomas, Enterprise JavaBeans Technology: Server Component Model for the Java Platform)

EJB 服務器為使用 EJB 組件的應用程序提供操作環境,並供應所有必需的服務,來支持 EJB 體系結構。打包 EJB 服務器軟件並沒有預先規定的方式。一種方法是將它作為一項功能增強包括到應用程序服務器中,這就是在 IBM WebSphere Application Server, Advanced Edition, Version 2.0 中采用的方法。

EJB 組件並不在 EJB 服務器的頂部直接執行。一個稱為 EJB 容器的中間軟件組件在 EJB 服務器環境中運行,從而又為這些 bean 自身提供操作環境。EJB 容器對 EJB 應用程序是完全透明的,但是在支持 bean 操作方面起著關鍵性的作用。

為了使 enterprise bean 能充當可重用的軟件組件,它們對特定的服務器或平台功能不能有內建的相關性。服務器端功能的幾種常見類型已經被從 bean 設計中“分離出去”,而將此功能的責任轉移給了容器組件。例如,容器將被用來接管安全性、並發性、事務處理、交換到輔助存儲器和其它服務的責任,從而使 bean 免受服務器相關性的制約,並將按業務邏輯來優化,而不是按服務邏輯來優化。

EJB 白皮書這樣描述容器的作用:

“EJB 容器管理部署於其中的 enterprise bean。客戶機應用程序並不直接與 enterprise bean 進行交互。相反,客戶機應用程序通過由容器生成的兩個封裝接口( EJB Home 接口和 EJB Object 接口)與 enterprise bean 進行交互。當客戶機使用封裝接口調用各種操作時,容器截獲每個方法調用,並插入管理服務。”(Thomas, Enterprise JavaBeans Technology: Server Component Model for the Java Platform)

可以期望 EJB 容器軟件一般都會隨 EJB 服務器軟件一起提供,盡管規范允許分離這些組件。除了提供對運行時服務(如事務處理和安全性)的訪問以外,還期望 EJB 容器包括各種必要工具,來支持 enterprise bean 的安裝、操作和管理。例如,需要有工具解釋 EJB jar 文件的內容,有工具生成數據庫訪問,來獲得容器提供的持久性,有工具監視正在運行的 bean 的行為,以及實現安全性等。

Bean 風格

EJB 組件分為兩種主要類別 -- 會話 bean 和實體 bean。根據 bean 處理狀態、事務和持久性的方式這些類別還可以進一步細分。會話 bean 通常具有以下屬性:

代表單個客戶機執行

可以是事務性的

可以更新共享數據庫中的數據

生存期相對較短

其生存期通常就是客戶機的生存期

任何持久性數據都由 bean 管理

可以依容器的判斷予以刪除

在 EJB 服務器失敗時被刪除

實體 bean 通常具有以下屬性:

代表數據庫中的數據

是事務性的

允許多個用戶共同訪問

可以長期存在

持久性數據可以由容器管理

在 EJB 服務器失敗後能繼續生存

EJB 規范對會話 bean 和實體 bean 的說明如下:

“對於客戶機,會話 enterprise bean 是一種非持久性的對象,它實現某些在服務器上運行的業務邏輯。想像一個會話對象的一種方式是:會話對象是運行在服務器上的客戶機程序的邏輯擴展。會話對象不在多台客戶機之間共享。

“對於客戶機,實體 enterprise bean 是一種持久性對象,它代表一個存儲在持久性存儲器(例如,一個數據庫)中的實體的對象視圖,或者是一個由現有企業應用程序實現的實體。”(Enterprise JavaBeans Specification 1.0)

用一種粗略的說法,會話 bean 代表這樣的操作,它檢索或存儲數據以滿足用戶請求;而實體 bean 則代表一種數據集,可以訪問這些數據集來滿足用戶請求。

會話 bean

最簡單的一種 Enterprise JavaBeans 組件就是無狀態的會話 bean。因為這些 bean 沒有可以區分它們的狀態,所有的實例都是完全相同的。容器管理無狀態會話 bean 的生存周期,其方式是通過創建足夠數目的此種 bean 來適應客戶機工作負荷,並在不需要它們時將其刪除。鈍化,即將閒置的 bean 寫到磁盤上,不用於無狀態的會話。要調用 bean,客戶機程序調用本地接口中的 standard create() 方法,盡管此操作不一定導致實例化新的 bean 實例。容器可以選擇將客戶機請求發送給現有的對象。反之,容器則可以按它的選擇創建新的實例,且獨立於由客戶機發布的 create() 方法。

在 EJB 本地對象上發布的 create() 調用返回一個對 EJB 對象的引用,這個 EJB 對象代表 enterprise bean。一旦客戶機有了 EJB 對象引用,它就可以將業務方法發布到 EJB 對象上,容器隨之會將這些方法委托給 bean 自身。負責管理會話 bean 的容器組件無需推斷會話 bean 是否是無狀態的。會話 bean 是無狀態的還是有狀態的在安裝時聲明。

如果會話 bean 在方法調用之間保留狀態信息,則它是有狀態的。通過調用 ejbPassivate() 方法,容器可以依其判斷將有狀態會話 bean 鈍化,或寫到輔助存儲器中。EJB 規范並不要求容器在鈍化 bean 時使用 Java 串行化協議,但是它們必須提供等價的功能。當容器決定將一個非活動的會話 bean 交換回到內存中時,它會取消被動 bean 的串行化,並調用 ejbActivate() 方法。有狀態會話 bean 的開發人員負責確保狀態數據是可串行化的。在集群的應用程序服務器環境中實現有狀態會話 bean 時務必要小心,因為並不是所有的服務器都支持集群的有狀態會話 bean 的同步化。

有狀態會話 bean 可以是事務性的。通過使用 javax.transaction.UserTransaction 接口中的方法,如 begin()、commit() 和 rollback(),bean 可以控制事務;通過實現 javax.ejb.SessionSynchronization 接口,bean 可以接收有關事務狀態的通知。EJB 容器無需推斷哪些 bean 需要事務支持;UserTransaction 接口僅可用於那些在安裝時被標記為事務性的 bean。

實體 bean

實體 bean 在體系結構上與會話 bean 類似,但它們提供對企業數據的訪問,而不是支持用戶會話。一個實體 bean 可以支持多個並發用戶,而容器則使訪問和事務同步化。實體 bean 還具有支持本地對象中的 finder 方法的主鍵。知道實體 bean 的主鍵的客戶機可以通過調用本地對象上的 findBy PrimaryKey() 方法獲得對象引用。與會話 bean 不同,實體 bean 的本地對象除了具有 create 方法外還具有 finder 方法。

持久性是實體 bean 的一個基本屬性。EJB 規范允許兩種形式的實體持久性:bean 管理的持久性和容器管理的持久性。對於代表關系數據庫中的數據的實體 bean,bean 對持久性的管理意味著,對數據庫訪問的調用是直接編寫在企業 bean 的方法中的(使用 JDBC 或 SQLJ)。這種方法是直截了當的,但它降低了可移植性。容器對持久性的管理意味著 bean 不受數據庫調用的影響。在安裝時告知容器有關 bean 數據所需的持久性,而容器負責生成實現持久性的代碼。這種方法允許 bean 的可移植性更高,甚至達到持久性可使用不同數據源的程度。然而,此方法要求容器中要有復雜功能。

當實體 bean 對象與 EJB 對象相關聯時,前者處於就緒狀態;否則將認為它們處於共享狀態。當客戶機調用 EJB 對象中的方法時,容器查找關聯的實體 bean 的實例(如果存在的話),或者從共享狀態中傳送出一個實例。處於就緒狀態的實體 bean 可以接收到通過委托從客戶機傳播給它們的業務方法調用。它們還可以在容器請求時執行 ejbLoad() 和 ejbStore() 方法。load 方法和 store 方法旨在維持實體 bean 和基礎數據存儲之間數據的一致性。

實體 bean 支持多個用戶並發地訪問數據。EJB 規范聲明,維持數據完整性是容器的責任:

“enterprise bean 開發人員在編寫業務方法時無需擔心來自多個事務的並發訪問。enterprise bean 開發人員在編寫方法時可以假定,對於被多個事務同時訪問的各個實體 bean,將能確保適當的同步化。”(Enterprise JavaBeans Specification 1.0)

容器完成這一任務通常是通過鎖定數據庫中的數據,並使訪問串行化,或通過創建實體 bean 的多個實例,並允許在基礎數據存儲中使用並發控制,這樣來管理訪問。

第三部分內容預告

“什麼是 Enterprise JavaBeans 組件?”的第三部分將討論安裝 EJB 組件的特殊部署過程。它還將說明 CORBA 是否是 EJB 組件的競爭對手(答案是“否” -- 請參閱 EJB 技術是如何補充 CORBA 的)。最後,您將看到一種基於 EJB 的三層編程模型的使用情況。

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