谈谈实体Bean

     想起了我的可爱的J2EE老师,决定把前一些日子学的东东总结一下,想到那里就总结那里吧...
     在EJB的技术体系中,实体Bean充当维护数据持久性的角色,它可能是最官方的O/R Mapping问题解决方案了吧。开发者可以利用实体Bean对关系数据库中的数据进行管理,EJB容器会为实体Bean提供可靠的服务支持,使实体Bean拥有可靠的性能。
     1. 那么什么是EJB容器呢?
     EJB容器为开发者提供了维护EJB对象的环境。在面向客户端的方面,EJB容器为EJB对象提供了客户端视图和接口,通过特定的传输协议可以实现EJB容器和客户端之间调用EJB对象的过程,这样使得底层的RMI等具体的协议对用户是透明的;在面向设备和资源方面,EJB容器对数据库、邮件服务器、事务服务、消息服务器等各种资源进行管理,使开发者不必或很少需要与这些资源直接发生关系。EJB在提供这些服务时,保证了EJB对象的稳定性,而且通过容器的一些机制对EJB对象的服务处理进行了优化。在EJB容器中包含了3种EJB组件:实体Bean,
会话Bean和消息驱动Bean。实体Bean的主要作用就像开始时说的一样是维护数据的持久性;会话Bean可以提供实现业务逻辑的方法;消息驱动Bean是基于JAVA消息技术的EJB对象,可以与JMS程序相配合,实现对消息列队的操作。
   
     2.下面我们来看看实体Bean的生命周期
      实体Bean是用来管理数据持久性的EJB组件,主要功能是管理对象与关系数据库之间发生的操作。每个实体Bean对应数据库表中的一行数据,建立或删除一个实体Bean相应的会导致数据库的一行记录被建立或删除。实体Bean的业务功能有开发者实现(BMP),或者由EJB服务器根据实体Bean的配置文件生成(CMP)。实体Bean的生命周期是由EJB服务容器负责管理和维护的,同时每个实体Bean都需要实现javax.ejb.EntityBean接口,这个接口中的方法与实体Bean对象的状态有关,具体的接口是这样的:
            public void ejbActivate() throws EJBException, RemoteException;
            public void ejbLoad() throws EJBException, RemoteException;
            public void ejbPassivate() throws EJBException, RemoteException;
            public void ejbRemote() throws RemoveException,EJBException, RemoteException;
            public void ejbStore() throws EJBException, RemoteException;
            public void setEntityContext(EntityContext ctx) throws EJBException, RemoteException;
            public void unsetEntityContext() throws EJBException, RemoteException;
      实体Bean在EJB容器中有3种状态:不存在、正在池中缓存和准备就绪。容器在创建实体Bean对象实例后,通过unsetEntityContext(EntityContext ctx) 方法将上下文传递给实体Bean对象,实体Bean进入缓存的状态,此时的实体Bean可以通过主接口提供一些方法,当实体Bean对象被激活进入就绪状态时,ejbActivate()方法被调用,此时实体Bean的对象与实体Bean的主接口相联系,可以提供相应的业务方法。在执行与数据库的交互时,容器通过ejbStore()和ejbLoad()方法来维护实体Bean状态。当实体Bean对象被返回对象池之前ejbPassivate()方法被调用,同时实体Bean对象再次回到缓存状态,这就是常常说的“钝化”。当实体Bean对象对应的EJB对象被从对象池中删除之前,ejbRomove()方法会被调用。当实体Bean被从对象池中删除时,unsetEntityContext()用来除去实体Bean对象的上下文对象。
    
     3 本地接口与远程接口有什么区别?
       在EJB2.0中,也就是我们上课在学的(虽然EJB3.0已经出来了),实体Bean能够提供的客户端视图有两种:远程接口方式和本地接口方式。
       当实体Bean发布远程接口方式时,被调用实体Bean和客户端的位置是无关的,也就是他们可以运行在不同的JVM之上,即使客户断与EJB容器在同一JVM,对于调用者来说,与客户端在远程的情况是一样的。EJB服务器通过Java RMI技术来提供实体Bean的远程视图,在客户端调用实体Bean时将参数和结果在双方之间进行传递。
       当实体Bean发布本地接口方式时,调用实体Bean的过程就有了很大的不同。最直接的影响是,位于EJB服务器JVM以外的客户端无法调用到这个实体Bean。当实体Bean提供本地接口时,客户端与EJB服务器之间不需要RMI来进行远程调用,而是通过传递实体Bean对象引用方式实现的。

     4.主接口和对象接口又有什么区别?
       EJB服务容器为每个实体Bean提供主接口和对象接口。当提供远程视图时extends主接口(EJBHome)和远程对象接口(EJBObject);当提供本地视图时extends本地主接口(NodeLocalHome)和本地对象接口(EJBLocalObject)他们的作用是不同的。
       主接口的作用是向客户端提供创建实体Bean、查找实体Bean、删除实体Bean和执行主接口操作的方法。在主接口中可以提供若干个创建方法,方法名称是create(),可以对其进行重载,这些方法均返回实体Bean实例。主接口中还提供若干个查找方法,这些方法以“find”作为名称的前缀。查找方法可以由容器实现,也可以由实现类来实现,这与实体Bean的类型和开发者设计有关。主接口还提供了删除实体Bean的方法,由容器来执行所以主接口是客户端与服务器端之间实现交互的接口,客户端可以借助JNDI获取实体Bean的主接口,对于远程视图来说可以通过如下的方法完成:
           Context ctx = new InitialContext(env);
           Object objRef = ctx.lookup("cmp/node");
           NodeHome home = (NodeHome)narrow(objRef, NodeHome.class);
     对于本地视图来说可以通过如下方法来完成:
           Context ctx = new InitialContext(env);
           Object objRef = ctx.lookup("cmp/node");
           NodeHome home = (NodeHome)objRef;
     对象接口向客户端提供了实体Bean的主要业务方法,通过对象接口可以完成对数据的操作,也可以通过它得到主接口,或者删除实体Bean对象。

     5. 实体Bean的类型:BMP与CMP
      实体EJB分为CMP和BMP。CMP(Container-Managed Persistence)的数据操作方法有开发者通过配置文件描述
CMP类型的实体Bean是应用最多的实体Bean类型。他使得开发者不必再去和复杂的JDBC API程序打交道,就可以完成高质量的数据操作组件,并且在EJB2.0标准中对CMP的内容进行了一些扩充,主要包括对EJB-QL和
CMR(Container-Managed Relationships)的支持。这里就不多作介绍了。
     BMP(Bean-Managed Persistence)类型的实体Bean是EJB中的另一种类型的实体Bean,在BMP的实现方法中,需要借助于数据库API来实现数据的操作。与CMP相比,BMP的优势是在于可以更加灵活第提供数据库操作方法,特别是对不支持使用CMP的数据库产品。
     在实际应用,一般为了效率考虑,我们尽量使用CMP,但如何为将来有可能使用BMP作好准备,就是说有可以延伸到BMP的基础。EJB 2.0对CMP的抽象类支持为我们提供了这种实现的基础。总体思路是,先使用抽象类完成CMP如果需要BMP,可以extend这个抽象类,然后覆盖原来的方法(用自己的特殊SQL语句操作来覆盖该方法)。
   
     啰嗦了这么多,你是不是有一种感觉,事情至于这么复杂吗?呵呵,这也是实体Bean被人诟病的最大原因,它是一个重量级的架构,而且它规范太臃肿和丑陋了,所以导致了很多轻量级的解决方案的流行,例如著名的Hibernate,ibatis等等,但是只有知道它的不足才能设计出好的方法,也算是知己知彼了,还是慢慢打好基础吧。

你可能感兴趣的:(JAVA之道,Bean,EJB,应用服务器,配置管理,JVM)