top
Loading...
一個無狀態的會話beans示例(5)
p align="JUSTIFY">為了使大家對EJB容器和Enterprisebeans有一個感性的認識,我們介紹一個簡單的client/server例子。就是Inprise的應用服務器自帶的例子--SortClient。是一個無狀態的會話beans,它實現了一個排序(sort)算法。本例子演示了如何編譯Enterprise beans例子,如何在EJB容器中運行Bean的一些基本操作。還演示了如何將一個對象放在JNDI命名服務中。

首先,我們來看一下Enterprise bean的原代碼。通常由Enerprise beans的提供者來編寫。(sort例子已經提供了代碼,所以我們實際上什么都不用寫。*_^)。下面,我們演示如何編譯和鏈接此Enterprise bean。如何配置,如何打包成應用程序。然后演示如何編譯鏈接客戶。最后才運行客戶和服務程序。

以下是開發具有Enterprisebeans的C/S應用程序的一些基本的步驟。

編寫Enterprise beans的代碼,包括beans的代碼中遠程(remote)接口和本地(home)接口的代碼。

編寫客戶端代碼。

編譯和鏈接源代碼,包括beans的和客戶的源代碼。

在目錄META-INF中產生一個配置描述器。

打包Enterprise bean。

將Enterprise bean配置到jar文件中。

運行客戶端。

編寫一個Enterprise bean:

所有的Enterprisebeans都由三個部分組成,都必須由Enterprisebeans的提供者編寫。這三個部分是:

實現類implementation class:這是一個Enterprisebean類,包括Enterprise beans應用邏輯的實現、和本地(home)、遠程(remote)接口的功能定義。對于Sort例子,實現類就是SortBean.java文件。

本地(home)接口:本地接口定義了createing,finding,removing Enterprise beans的操作。在我們這個例子中,本地接口就是SortHome.java文件。

遠程(remote)接口:遠程接口定義了一些對客戶可用的應用邏輯的方法。由Enterprisebeans提供。本例中,遠程接口就是Sort.java文件。

客戶要能夠調用Bean的應用邏輯方法,Bean必須由這三個組成部分。客戶應用程序使用Home接口來定位beans的remote接口。一旦客戶擁有了remote接口的引用(refereenece),就? 調用在remote接口中聲明的任何方法。客戶并不知道方法是在本地還是在遠程系統中執行。對客戶而言,調用Enterprise beans的方法就和調用本地方法一樣簡單。EJB容器將遠程調用傳遞給實際的Enterprisebeans的實例。控制所有的通信協議,并通過remote接口將返回值傳給客戶。

下圖顯示了當SortClient客戶需要調用SortBean 會話bean的merge()方法的時候的可能發生的調用情況。注意,SortClient首先調用SortHome接口的Create()方法。返回了Sort的remote接口的一個引用。然后,客戶端才調用Sort remote接口的merge()方法。方法傳回了所需要的結果。

EJB 容器
Create Sort 的實例
Sort的引用
Merge函數
結果

例子Sort是一個無狀態的會話bean。大多數的會話beans都有狀態。在會話中,應客戶的要求,容器產生一個bean的實例。并且在整個會話中,這個實例都為這個這個特定的客戶服務。根據定義,一個有狀態的會話bean在整個會話的過程中都保持著與客戶的會話狀態。

另一方面,無狀態的狀態bean并沒有指向某一個特定的客戶,也就是說,說它并沒有保持著與客戶會話的任何狀態。當客戶調用一個無狀態的會話bean方法時,容器給客戶指定一個在緩沖池中的beans實例為之服務。被指定的實例保持著方法有關的變量,一直到完成方法調用。實例在方法調用的時候就返回的狀態是任意值。而自己卻不保存任何的狀態,也不再與調用它的客戶相聯系。容器可以將實例歸還給實例緩沖池,也可以不歸還給緩沖池而由系統自動處理。

編寫本地(home)接口:

home接口定義了創建(create),查找(find),刪除(remove)等方法。無狀態會話bean的home接口要比有狀態的會話bean或者實體bean的home接口要來得簡單。SortHome的home接口擴展了javax.ejb.EJBHome接口,聲明了create()方法。Create()方法沒有參數,拋出兩個異常:RemoteException和CreateException。

Create()返回了一個類型為Sort的對象,它實際上是一個對remote接口的一個引用。注意,客戶并沒有直接調用beans實例的任何方法。客戶只是調用了通過beans的remote接口調用在remote接口定義了的方法。

因為有狀態的會話bean和實體bean保持了客戶的狀態,可以有多個方法來產生實例,可以傳遞初始的參數給Create()方法。而無狀態的會話bean并不需要保存客戶的狀態,可以只有一個Create()方法。這個唯一的Create()方法不能含有任何參數。將beans實例從實例緩沖池中取消的方法是Remove()方法,這是從EJBHome中繼承過來的,而不需要另外在SortHome的Home接口中聲明。

Sorthome的home接口如以下代碼所示:

//SortHome.java
public interface SortHome extends javax.ejb.EJBHome(
Sort create() throws java.rmi.RemoteException, javax.ejb.CreateExcepion;)

編寫remote接口代碼:

remote接口定義、發布了Enterprise bean的應用方法,使這些應用方法可以在客戶端被調用。它擴展了javax.ejb.EJBObject接口。Remote接口中的每一個方法都必須與SortBean實現類中的聲明相匹配。方法必須有同樣的名字和標識。另外,在sort的remote接口中必須拋出java.rmi.RemoteException異常,必須返回有效的RMI類型。Sort的remote接口聲明了兩個方法:sort()和merge()。兩個方法都拋出了java.rmi.RemoteException異常,都返回了Vector類型。如下代碼就是Sort的Remote接口:

//Sort.java
import java.util.Vector;
public interface Sort extends javax.ejb.EJBObject{
Vector Sort(Vector v, Compare c) throws java.rmi.RemoteExcetpion;
Vector merge(Vector a, Vector b, Compare c) throws java.rmi.RemoteException;
}

編寫會話bean的實現代碼:

因為SortBean是一個會話bean。必須實現javax.ejb.SessionBean接口。同時也要注意,SortBean類要定義成公共的。

SortBean的實現類定義了一些應用方法可以供客戶端調用。在這個例子中,SortBean定義了sort()和merge()兩個方法的實現。運行客戶應用程序時,將會調用兩個方法。

一個會話bean實現了ejbCreate()的方法,并且與home接口中的Create()方法相對應。SortHome的home接口定義了一個無參數的Create()方法,拋出了一個java.rmi.RemoteException異常。但是,與Sorthome接口的create()方法不同,create()返回了一個sort類型的對象,而ejbCreate()方法返回的是void類型。

會話bean可以有一個公共的構造函數,而SortBean卻不可以。SortBean除了創建和應用方法以外,另外有四個方法,它們是:ejbRemove(),ejbActivate(),ejbPassivate(),和setSessionContext()。容器擁有這些方法的句柄,在Sortbean里,只需要將這些方法聲明為public并將返回值置為void。

下面是會話bean:SortBean的實現類的源代碼:為簡潔起見,我們并沒有完全顯示sort()方法和merge()方法的實現部分。也沒有把調試信息給顯示出來。

//SortBean.java
import java.util.Vector
public class SortBean implements javax.ejb.SessionBean{
public void setSessionContext {javax.ejb.SessionContext
sessionContext} {}
public void ejbCreate() throws java.rmi.RemoteException {}
public void ejbRemove() throws java.rmi.RemoteException {}
public void ejbActivate() throws java.rmi.RemoteException {}
public void ejbPassivate() throws java.rmi.RemoteException {}
public Vector sort (Vector v, Compare c) throws java.rmi.RemoteExcetpion{
try{

……

return result;

}

catch(javax.ejb.CreateException e){
throw new java.rmi.ServerException(“Could not create sort instance”, e);
}
catch(javax.ejb.RemoveException e){
throw new java.rmi.ServerException(“Could not remove sort instance”,e);
}
}
public Vector merge(Vector a, Vector b, Compare c) throws java.rmi.RemoteException{
…….
}
}
}

編寫客戶端代碼:

客戶端程序SortClient,必須首先使用JNDI的API來定位Enterprise beans的Home接口。在下面的例子代碼中,SortClient客戶首先端生成了一個JNDI上下文,使用JDNI的的lookup方法來為sort定位home接口。

//SortClient.java
public class SortClient{

public static void main(String[] args) throw Exception{
java.name.Context context;
{ //get a JNDI context using the Naming Service
context = new java.naming.InitialContext{};
}
Object objref = {SortHome} context.lookup(“sort”);
SortHome home = {SortHome} javax.rmi.PotableRemoteObject.narrow{
Objref, SortHome.class}
Sort sort = home.create();
…//do zhe sort and zhe merge work.
Sort.remove();
}
}

在獲得了SortHome的引用之后,客戶就能夠調用home接口的create()方法來獲得Sort的remote接口的引用。一旦客戶有了SortBeans的remote接口引用。就能夠象調用普通方法一樣調用remote接口的sort()方法和merge()方法。

編譯鏈接Sort會話bean和它的客戶端:

我們用一個makefile文件編譯鏈接了sort 會話 bean和它的客戶端。Makefile文件做了java2iiop,jar,verify等實用工具做的工作。首先,正確的設置環境變量-CLASSPATH和PATH

然后編譯和build你的例子:

prompt% makeall
make文件非常簡單,需要的話,可以自己修改它。
Sort的makefile文件如下:
#makefile
default: all
include http://www.zhujiangroad.com/Makefile.rules
SRCS=
SortClient.java
SortHome.java
SortBean.java
CLASSES = $(SRCS:.java=.class)
Beans.jar: $(CLASSES}
$(JAVA2IIOP) SortHome
$(JAR) cMf beans.jar META-INF *.class
$(VERIFY) beans.jar
all: $(CLASSES) beans.jar

生成配置描述器:

配置描述器是一個XML文件, 在XML文件里面定義了Enterprise bean的屬性。可以通過標準的XML編輯工具來生成XML文件。然后,就可以用配置描述編輯器來編輯。

注意:如果你用的是標準的XML編輯器,必須保證符合EJB1.1的規范要求。這樣,Enterprise bean才能夠與EJB容器一起工作。必須使用Inprise的文件類型定義(DTD)。目前,必須用標準的配置描述生成器來生成一個配置描述。一旦配置描述成為了jar文件的一部分。就可以用配置描述編輯器來修改它。配置描述器提供了Enterprise bean代碼的配置信息,可以通過編輯器來更改它。

Enterprise beans是可以用在不同的應用程序,而不修改其源代碼的。但是,因為每個應用程序按照它自己的方式來使用Enterprise beans。使用配置描述器就能夠讓beans適應這樣的不同。SortBean的描述器定義了它的類型(無狀態的Session),指定了其home接口(SortHome)和remote接口(Sort)的名字。還指定了其事務的類型(容器管理的事務)。

最后,運行例子Sort:

要運行例子,首先要啟動VisiBroker Smart Agent來處理初始化的接口調用(例如客戶如何定位命名服務等)。Smart Agent是通過應用服務器來運行的。

用如下命令啟動EJB容器:

prompt% vbj com.inprise.ejb.Container. ejbcontainer sort_beans.jar -jts -jns

從一個終端窗口用如下命令運行客戶端程序:

promtp% vbj SortClient

客戶定位并調用SortBean來對一組數組進行排序。輸入輸出如下:輸入(用in標志的行),輸出(用out標志的行)的數據。當然,并不一定要一模一樣。根據你的輸入數據的不同,將產生不同的輸出。但其形式是這樣的。

in: [1]
out:[1]
in: [1,2]
out:[1,2]
………
……….
In:[this is a test]

作者:http://www.zhujiangroad.com
來源:http://www.zhujiangroad.com
北斗有巢氏 有巢氏北斗