EJB 程式設計模型 (轉)

worldblog發表於2007-12-08
EJB 程式設計模型 (轉)[@more@]

本文的第二部分說明建立
Enterprise Bean 所需的 Java 介面和類的作用。除了對 bean 類本身進行編碼外, 開發人員還必須為 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 介面。這些強制性介面必須擴充套件標準的 EJB 和 EJBHome 介面,而這兩個介面則都是 java..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/shop_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 監視器、
執行時系統、執行時系統、系統、 伺服器系統或其它基於伺服器的執行時系統)都可以調整到能夠支援可移植的 Enterprise
JavaBeans 元件。”(Thomas, Enterprise JavaBeans Technology: Server Component Model
for the Java Platform)


 

EJB 伺服器為使用 EJB 元件的應用程式提供操作環境,並供應所有必需的服務,來支援 EJB 體系結構。打包 EJB
伺服器軟體並沒有預先規定的方式。一種方法是將它作為一項功能增強包括到應用程式伺服器中,這就是在 IBM 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
的主鍵的客戶機可以透過呼叫本地物件上的 finy PrimaryKey() 方法獲得物件引用。與會話 bean 不同,實體 bean 的本地物件除了具有
create 方法外還具有 finder 方法。


 

永續性是實體 bean 的一個基本屬性。EJB 規範允許兩種形式的實體永續性:bean 管理的永續性和容器管理的永續性。對於代表關聯式資料庫中的資料的實體
bean,bean 對永續性的管理意味著,對資料庫訪問的呼叫是直接編寫在企業 bean 的方法中的(使用 或
J)。這種方法是直截了當的,但它降低了可移植性。容器對永續性的管理意味著 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 的多個例項,並允許在基礎資料儲存中使用併發控制,這樣來管理訪問。


 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-989767/,如需轉載,請註明出處,否則將追究法律責任。

相關文章