一个无状态的会话beans示例(5)


为了使大家对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 ../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]

本文作者:
« 
» 
快速导航

Copyright © 2016 phpStudy | 豫ICP备2021030365号-3