EJB概述
在J2EE中,有WEB组件和EJB组件,EJB组件位于业务层,主要用于实现业务层的逻辑。
J2EE将业务逻辑从客户端软件中抽取出来,封装在一个组件中。
EJB提供的接口往往不需要改变,只是实现了接口的逻辑过程需要改变。
EJB的实现技术
通过RMI技术,J2EE将EJB组件创建为远程对象,客户端使用JNDI技术查找EJB对象
RMI(远程方法调用)
生成远程对象必须要先定义远程接口,然后再编写它的实现类。在开发EJB组件时,也是要先定义远程接口的,但却不用编写它们的实现类。远程对象的实现类是由EJB组件所运行的容器自动实现的,不同的容器生成的实现类文件可能是不一样的。
EJB组件包含了两个接口文件,一个是REMOTE接口文件,另一个是HOME接口文件。
这两个接口都是远程接口,因为它们都有间接地扩展了java.rmi.Remote接口,并且在声明的方法都抛出了java.rmi.RemoteException异常。Remote接口中声明的方法是EJB中实现了业务逻辑的业务方法。而Home接口则声明了如何生成EJB对象的create方法(实体EJB还包含finder方法)。容器在运行EJB组件时,会先生成一个home对象,这个对象就是Home接口实现类的对象实例。客户端程序在调用时,首先要通过JDNI查找到Home对象,然后再调用Home接口中提供的创建EJB对象的方法返回一个EJB对象的引用。因此,EJB组件中真正的EJB对象是由容器生成的Remote接口实现类的对象,而它是由Home对象中的创建方法生成的。
对于不同的客户端,它们所需要的EJB对象可能并不是一样的。尤其是在创建实体EJB时,有时是通过数据库的原有的数据创建实体EJB,有时则是根据一个新的数据记录创建实体EJB。如果说只是统一返回一致的EJB,就无法体现这些差异了。Home对名象实际上就是提供了一个定制EJB的手段。
EJB技术的高明之处在于它虽然使用了RMI技术,但是却只需要定义远程接口而无需生成它们的实现类,这样就将RMI技术中的一些细节问题给屏蔽了,使得EJB组件更具有通用性。
RMI中的Remote接口与EJB中的接口区别:
RMI中的Remote接口是指扩展了java.rmi.Remote接口的接口;而EJB中的Remote接口则
指扩展了 java.ejb.EJBObject接口的接口,对于具有本地视图的EJB则要扩展javax.ejb.EJBLocalObject接口。
从EJB开发人员的角度来说,一个EJB组件由四个部分组成,即Home接口,Remote接口,Enterprise Bean 类和部署描述文件。
从容器角度来看,它从EJB中读取部署描述文件,通过部署描述文件提供了信息生成Home对象和EJB对象,Enterprise Bean 对象,并回调Enterprise Bean对象中提供了方法,实现EJB对象所需要的一些服务。对于EJB来说,有两种用户可以调用它的方法。一种是远程客户,另一种是本地客户,所以EJB提供本地视图和远程视图。
容器是EJB组件是代理,开发人员除了要提供客户端可以调用的业务方法,还要提供一些容器可以回调的方法。如ejbActivate,ejbPassivate等。
本地地客户调用EJB对象时是通过本地视图,而远程客户调用EJB对象则是通过远程视图。本地用户可以通过远程视图调用EJB对象,但是远程客户却不能通过本地视图调用EJB对象。
Enterprise Bean 类并不是Home接口或Remoter接口的实现类,容器在运行时会将这个类中定义的EJB创建方法和业务方法抽取出来,并用它们去实现Home接口和Remote接口。最后类中只留下可供容器回调的方法,用于实现容器对EJB对象的管理。
EJB2.1中定义了三种不同类型的EJB,它们是会话Bean(Session Bean),实体Bean(Entity Bean)和消息Bean(Message-driven Bean)
会话Bean是一个应用逻辑组件,表示的是客户要求完成的任务。网上购物车就是一个会话Bean,它实现了客户可能要求的各种任务,如添加商品,删除商品,结帐等。
会话Bean不是持久数据对象,也不会存储在数据库中。所以当服务器或容器发生意外时,会话Bean就不复存在了。
每个客户在与服务器会话时,都会占有一个特定的会话Bean,在会话过程中其它客户机不能同时访问这个Bean。
根据容器对会话状态管理的不同,会话Bean分为无状态会话Bean和有状态会话Bean.
无状态会话Bean不存储与客户进行会话过程中的信息,有状态会话则能保持客户状态的变化(只是一个暂时保存)
一般通过实体Bean将数据对象化,然后在会话Bean中通过实体Bean对数据进行访问.
实体Bean是一个持久数据组件,表示底层数据的对象模式。实体Bean不包括业务逻辑,它们只是将底层数据对象化,便于数据操作。
根据实体Bean持久管理机制不同,可以将实体Bean分为Bean管理持久机制(bean-managedpersistence,BMP)的实体Bean和容器管理的持久机制(container-managed persistence,CMP)的实体Bean.
消息Bean用于听取JAVA消息服务(JMS)输入的消息。消息Bean没有向客户端公开的接口,要与消息Bean进行通信必须通过向其发送JMS消息来实现。由于消息Bean没有公开接口,所以消息Bean没有home和Remote接口。
EnterpriseBean 类并没有实现Home接口,Remote接口或Local接口,它只是说明这两个接口中方法应该如何实现。Enterprise Bean 类真正实现的接口是javax.ejb.EnterpriseBean接口。
Home接口形式:
Public interface javax.ejb.EJBHome extends java.rmi.Remote
{
public abstract EJBMetadata getEJBMedata()
throws java.rmi.RemoteException;
public abstract HomeHandle getHomeHandle()
throws java.rmi.RemoteException;
public abstract void remove(Handle handle )
throws java.rmi.RemoteException,java.ejb.RemoveException;
public abstract void remove(Object primaryKey)
throws java.rmi.RemoteException,java.ejb.RemoveException;
}
public interface javax.ejb.EJBLocalHome
{
public abstract void remove(Object primaryKey)
throws RemoveException,EJBException;
}
在开发EJB时,必须要定义Home接口,它们的作用是声明创建、删除和查找EJB对象的方法。但是不用编写实现类,其由容器自动生成。
getEJBMetaData()用于获取EJB的EJBMeatdata对象,EJBMeatdata对象封装了EJB的各种信息:如EJB种类等。
getHomeHandle()用于获取远程Home对象的句柄。
remove(Handle handle)通过EJB对象的句柄清除EJB对象
remove(Object primaryKey) 通过主键清除EJB对象,只能应用于实体Bean
EJB开发人员在定义接口时就是将所有用于生成EJB对象的create方法和finder方法写入到接口文件中。
一个无状态会话Bean
package firstejb;
import javax.ejb.*;
import java.util.*;
import java.rmi.*;
public interface FirstHome extends javax.ejb.EJBHome{
pulbic First create() throws CreateException,RemoteExcetion;
}
}
}