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

Enterprise JavaBeans入門

編輯:關於JAVA

EJB(Enterprise JavaBeans)可不算什麼新概念了,但許多人在聽到或者看到這個名詞的時候還會眼暈。EJB組件在J2EE規范中自成一層,把應用程序的表示層和後端信息系統(比如數據庫或者主框架計算機)捆綁了起來。EJB架構既用到了EJB對象的功能又利用了它們所運行的環境。

為什麼出來個EJB

從概念上看,EJB對象封裝了業務對象及其概念,讓開發人員把精力集中於解決方案的細節之上。從設計的角度看,EJB應該輕便而相互影響地合並起來。這一舉措可以令單一的EJB,不論其是否為商務應用程序就可能采用一個EJB代表自主開發還是第3方廠商開發卻都能用於多種應用程序。比方說,CRM(客戶關系管理)工具和電子一位用戶。這些已經具有適應性對象的配置由於部署描述符、說明EJB的XML文件而變得非常簡單。部署描述符允許不經重新編譯就可修改EJB屬性和行為。

EJB的處所

EJB對象駐留在EJB容器內,後者是向開發者提供各類服務的環境。容器根據具體的配置可能負責處理安全、事務和實例管理。由於程序員無須再親自完成這些任務從而令開發時間大大節約。

J2EE服務器和EJB容器這兩個概念之間存在顯著差別, EJB容器可能屬於J2EE服務器的一部分,但卻並不一定是必需的組成部分。在作為J2EE服務器組成部分的情況下,EJB客戶程序通常會采取Java servlet或者JSP的形式。不過,由於取消了對J2EE Web層的依附性,標准的EJB容器服務可以接受多種類型客戶程序、用Java或其他各種語言編寫的應用程序所發出的請求。同EJB容器的通訊才是客戶操作的先決條件。

EJB的內容

EJB對象分為以下三種類別:

會話Beans

實體Beans

消息驅動Beans

根據所需要的bean行為,某些特性決定了所采用的Bean類型。

會話Beans

會話(Session)Beans的作用建立在會話的基礎之上。客戶在請求並收到bean功能之後,具有特定bean的會話就終止了而且沒有留下會話發生的記錄。會話Bean類型還可以進一步細分為無狀態或者有狀態方式。

無狀態會話Beans並不知道客戶或者涉及到請求的上下文,從而令其成為單一請求/回應應用的理想工具。比方說,一個用戶搜索所有公開bug的bug跟蹤系統就是如此。客戶應用程序聯系一個無狀態會話Bean並給其傳遞搜索參數。接著,這個bean訪問數據庫,選擇匹配檢索條件的條目,並把記錄傳回客戶程序。通訊完成之後,bean不保留交互信息。因此,多個客戶程序可以同時訪問無狀態會話Bean卻不會相互影響。

相反,有狀態會話Beans會把請求同特定的客戶聯系起來,在客戶和bean之間建立一種一對一的關系。購物車bean就是一例。用戶實施標准的電子商務任務,給購物車裡加入商品,輸入地址信息然後下定單。購物車bean維持狀態,因而它知道所有這些變量都關聯某一特定客戶。

實體Beans

實體(Entity)Beans表示會話終止之後持久存在的業務對象或者數據。它們通常作為數據庫中的單一記錄形式存在,當然,其存儲形式也可能采用其他媒質,比如文件等。一個對象就表示一個用戶,有名字、聯系方式、語言選擇等等,這些參數代表了實體Bean的用途。作為持久性最本質的內涵之一,實體Bean的唯一標識或者主鍵起到了識別和檢索正確對象信息的作用。實體beans需要主鍵作為“輔助類”封裝對象的唯一標識符。

消息Beans

以上的兩種bean類型以同步方式為EJB客戶提供服務。客戶發出請求然後等待bean發回結果。消息驅動(Message Driven) Beans避免了這一可能的瓶頸問題。采用Java消息服務JMS(Java Messaging Service)。客戶程序可以產生一個消息並把消息發布給消息隊列。消息驅動Bean隨之采用或者檢索消息執行其內容。這種事件或者數據的通訊就成為異步形式;客戶或者bean都無須依賴對方的直接響應了。

比如,倫敦的一位銀行官員使用一種應用程序發布最新的匯率消息。這時,部署在波士頓的一個外部交易bean從消息隊列中獲取這一消息然後更新數據庫中的有關記錄。在理想的情況下,消息驅動Bean會把信息傳遞給處理數據庫事務的實體Bean。這樣,每一種bean把它不能處理的任務轉發從而創建出一種真正的分布式組件結構。

EJB的原理

現在不考慮EJB的類別,以上三種類型組成了EJB對象:本地接口、遠程接口和bean的實現。客戶程序使用Java命名和目錄接口JNDI(Java Naming and Directory Interface)定位bean的本地接口(JNDI)。本地接口隨後返回遠程接口的實例,同時暴露必要的bean實現方法。客戶程序再調用適當的這些方法。程序清單A所示的代碼說明了以上過程。

Listing A

First comes the EJB client class—in this case, a very simple stand-alone user interface:
import javax.ejb.*;
import javax.naming.*;
import java.util.*;
import org.shifter.ejb.*;
public class VerySimpleClient
{
public static void main( String[] args ) {
try {
Context ctx = getInitialContex(); VerySimpleHome home = ( VerySimpleHome )ctx.lookup( "simpleton" );
VerySimple ejb = home.create();
ejb.setName( "Fredrick" );
System.out.println( "My name is " + ejb.getName() );
ejb.remove();
} catch (Exception e) {
e.printStackTrace();
} }
public static Context getInitialContext() throws NamingException {
// Retrieve the Context via JNDI lookup
} }
Now, we define the Home and Remote interfaces. The client interacts directly with these classes:
package org.shifter.ejb;
// The home interface import javax.ejb.*; import java.rmi.RemoteException;
public interface VerySimpleHome extends EJBHome {
public VerySimple create() throws CreateException, RemoteException; }
package org.shifter.ejb;
// The remote interface import javax.ejb.*;
import java.rmi.RemoteException;
public interface VerySimple extends EJBObject {
public String getName() throws RemoteException;
public void setName( String n ) throws RemoteException; }
Finally, we have the implementation of the EJB, where all functionality occurs:
package org.shifter.ejb;
import javax.ejb.*;
public class testertwoEJB implements javax
// Called by the create() method of the home interface.
public void ejbCreate() { }
// Called by the remove() method of the home interface.
public void ejbRemove() { }
// Called when the EJB container makes this bean active.
public void ejbActivate() {
// Resource allocation might go here.
}
// Called when the EJB container makes this bean inactive. public void ejbPassivate() {
// Resource clean up might go here. }
// Set the runtime context
public void setSessionContext(SessionContext ctx) { this.ctx = ctx; }
// *****
// The following methods are the only ones visible
// to EJB clients through this bean’s remote interface.
// *****
public String getName() {
return name; }
public void setName( String n ){
name = ( n != null ) ? n : "Igor"; } }

你可能需要根據bean的類型實現其他方法。比方說,假如客戶需要定位實體Bean,那麼你的本地接口就要包括findByPrimaryKey()方法,由它把主鍵類作為其參數以返回適當的對象。

早先提到過,每一個EJB對象所包裝的部署描述符會告訴EJB容器對象的行為如何。描述符之一,也就是所謂的ejb-jar.xml就是完成以上功能的,它是具有容器管理事務所有方法的無狀態會話Bean,如程序清單B所示。

Listing B

<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>VerySimple</ejb-name> <home>org.shifter.ejb.VerySimpleHome</home> <remote>org.shifter.ejb.VerySimple</remote>
<ejb-class>org.shifter.ejb.VerySimpleEJB</ejb-class> <session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>VerySimple</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>

根據EJB容器的類型,另一種部署描述符會告訴容器如何識別和定位采用JNDI的bean。以WebLogic服務器為例,起這一作用的就是weblogic-ejb-jar.xml,情形如程序清單C所示。

Listing C

<weblogic-ejb-jar>
<weblogic-enterprise-bean>
<ejb-name>VerySimple</ejb-name>
<jndi-name>simpleton</jndi-name>
</weblogic-enterprise-bean>
</weblogic-ejb-jar>

喜憂摻半

EJB的使用會涉及到某些內在的危險和可能的問題。程序員在給EJB對象編碼的時候必須遵守大量的語法和行為規則。它們還必須確定到底是采用bean自身還是EJB容器的持久性管理;選擇錯誤就可能都是數據。容器甚至可能崩潰從而破壞活動的會話Beans。容器還可能在嘗試回滾事務的時候失敗而喪失信息。部署EJB對象是一個單調反復的過程,在沒有容器源代碼的情況下進行調試工作幾乎是不可能的。

不過,EJB的組件天性卻令其代碼的重用性優勢凸顯,從而節約了開發過程中的大量時間和金錢。開發人員可以把關注點集中於業務邏輯本身,而把安全和事務回滾等任務交付給EJB 容器。可靠的對象實例管理和方便的配置更是EJB的突出優點。學習和掌握EJB的設計規則確實是一件很費時間和精力的工作,但其結構本身在應用程序的開發過程中會產生非常有益的好處。

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