为了使大家对EJB容器和Enterprisebeans有一个...">
一个无状态的会话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)接口的代码。
编写一个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()方法。方法传回了所需要的结果。
例子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接口如以下代码所示:
编写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接口:
编写会话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()方法的实现部分。也没有把调试信息给显示出来。
编写客户端代码: 客户端程序SortClient,必须首先使用JNDI的API来定位Enterprise beans的Home接口。在下面的例子代码中,SortClient客户首先端生成了一个JNDI上下文,使用JDNI的的lookup方法来为sort定位home接口。
在获得了SortHome的引用之后,客户就能够调用home接口的create()方法来获得Sort的remote接口的引用。一旦客户有了SortBeans的remote接口引用。就能够象调用普通方法一样调用remote接口的sort()方法和merge()方法。 编译链接Sort会话bean和它的客户端: 我们用一个makefile文件编译链接了sort 会话 bean和它的客户端。Makefile文件做了java2iiop,jar,verify等实用工具做的工作。首先,正确的设置环境变量-CLASSPATH和PATH 然后编译和build你的例子:
生成配置描述器: 配置描述器是一个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容器:
从一个终端窗口用如下命令运行客户端程序:
客户定位并调用SortBean来对一组数组进行排序。输入输出如下:输入(用in标志的行),输出(用out标志的行)的数据。当然,并不一定要一模一样。根据你的输入数据的不同,将产生不同的输出。但其形式是这样的。
|