【分布计算环境学习笔记】4 Enterprise Java Bean

作者:gnuhpc
出处:http://www.cnblogs.com/gnuhpc/

1.基本概念:

EJB是用于开发和部署多层结构的、分布式的、面向对象的Java 应用系统的跨平台的构件体系结构。采用EJB可以使开发商业应用系统变得容易,应用系统可以在一个支持EJB的环境中开发,开发完之后部署在其他的环境中,随着需求的改变,应用系统可以不加修改地迁移到其他功能更强、更复杂的服务器上 .

2.特点:

  • EJB是用Java语言开发分布式的、面向对象的企业应用系统的标准构件体系结构,EJB使得通过组合构件得到分布式应用成为可能
  • EJB不需要应用开发人员了解底层的事务处理细节,状态管理,多线程,资源共享管理,以及其它底层API细节.
  • EJB遵循Java的“write once, run anywhere”的原则.一个EJB可以部署在任何EJB平台上.
  • EJB定义了一个协议,使得不同供应商提供的构件能在运行时互操作.
  • EJB体系结构和已有的服务器平台,其它的Java  APIs, CORBA兼容
  • EJB通过定义一系列标准的服务API来封装现有的基础性服务,EJB应用通过这些标准的API来使用服务;
  • EJB可以在不修改源代码的基础上进行定制:EJB应用可以通过部署描述符(Deploy Descriptor)进行定制化,厂商可以进行自己的扩充,以支持更强的可定制特性:很多厂商除了J2EE标准的DD(ejb-jar.xml)外,还会有一个厂商特定的辅助部署描述符,其中描述了厂商自己扩充的运行时可定制特性。

3.三个关键构件:

  • EJBHome 接口(扩展javax.ejb.EJBHome接口):使用了factory设计模式,定义了创建、查找EJB的方法,接口由EJB容器创建,用户可通过JNDI来得到每个构件相应的Home接口,通过此Home接口来创建、删除EJB对象、构件以及相应的信息.EJB Home Interface:EJB 2.0中引入了本地接,客户能够通过Beans的home接口,定位到某个beans,并产生这个beans的一个实例。这样,客户就能够调用Beans的应用方法和远程接口。
  • EJBObject接口(扩展javax.ejb.EJBObject接口):使用了proxy设计模式,定义了在bean中实现的业务逻辑方法。EJB对象类似于EJB构件的“代理”,由EJB Home接口创建,客户端程序通过EJB对象来调用服务器端构件的方法。
  • Bean实现类(实现javax.ejb.EntityBean/SessionBean):实现业务逻辑。

 

image  

4.几个基本对象和接口:

EJB对象
    1.由容器生成的。
    2.实现了远程接口或本地接口。
    3.客户端通过EJB对象委托调用enterpriseBean的方法。

客服端调用EJB对象的几个基本步骤——设置JNDI服务工厂以及JNDI服务地址系统属性,查找Home接口,从Home接口调用Create方法创建Remote接口,通过Remote接口调用其业务方法。

远程接口 :远程访问使能,客户通过iiop (IIOP ,它是一个用于CORBA 2.0及兼容平台上的协议。这个协议的最初阶段是要建立以下几个组件部分:一个IIOP到HTTP的网关,使用这个网关可以让CORBA客户访问WWW资源;一个HTTP到IIOP的网关,通过这个网关可以访问CORBA资源;一个为IIOP和HTTP提供资源的服务器,一个能够将IIOP作为可识别协议的浏览器)调用访问CORBA,客户和EJB可以是分布的。其参数和返回按值传递,要求可以通过网络能传递。

    1.继承javax.ejb.EJBObject。
    2.定义并公开enterpriseBean的方法。
    3.客户端通过该接口与容器生成的EJB对象交互。
    4.其中定义的方法都必须抛出java.rmi.RemoteException异常。这是必须的,因为它继了EJBObject,而EJBObject实现了Remote接口。
    5.客户端通过远程接口调用enterpriseBean的效率是很底的。原因如下:  
      (1)首先客户端需调用本地Stub。  
      (2)Stub将参数格式化为适合网络传输的格式。
      (3)Stub与服务器端的Skeleton连接。
      (4)Skeleton解释被Stub格式化了的参数。
      (5)Skeleton调用EJB对象。
      (6)EJB对象连接缓冲,事务处理,安全检查,生命周期服务等工作。
      (7)调用enterpriseBean的业务方法。当enterpriseBean完成任务,返回Home时,将重得执行以上步骤。

本地接口 :跟一般的接口没什么区别,客户和EJB在同一JVM中运行,参数和返回值没有限制,速度较快。
    1.继承javax.ejb.EJBLocalObject。
    2.本地用户可以通过本地接口高性能的访问EJB对象。(免去执行远程接口中的第5项工作)

Home接口 :通过远程调用创建或查找EJB.与远程接口对应,有相似的限制。
    1.继承javax.ejb.EJBHome。
    2.用来创建EJB对象。
    3.其中有个Create方法返回容器实现了远程接口的EJB对象。并抛出两个异常。java.Rmi.RemoteException和javax.ejb.CreateException。

本地Home接口 :通过本地调用创建或查找EJB,与本地接口对应。
    1.继承javax.ejb.EJBLocalHome。
    2.同本地接口相同,它是本地客户端可以使用的高性能Home接口。
    3.其中有个Create方法返回容器实现了本地接口的EJB对象。抛出javax.ejb.CreateException异常

 

5.分类:

a.实体Bean:

实体bean用来表示持久存储库里的一个东西。这通常就是指数据库里的一个东西,实体bean的一个实例就表示数据库表中的一行(不过,如果数据库得到了规范化,bean也有可能从多个表的数据行提取信息,也就是说,可能对应到多个表中的多个数据行)。实体bean的一个典型例子就是Customer(顾客), 一个Customer实体bean可能表示BoOlean(ID# 343) ,另一个Customer实体bean可能表示的是Trixia Lin(ID# 870)。实体Bean有两种操作类型:BMP(Bean管理持久性)和CMP(容器管理持久性)。BMP是指由Bean自己来实现实体Bean的持久性,即在Bean中实现数据库操作。而CMP则是由容器实现Bean的持久性,使我们不需要在Bean内再编写数据库操作的代码,但需要在部署描述符中写EJB QL语句。

b.消息驱动Bean(EJB2.0新增的类型):

只有在需要一个JMS(Java消息服务)客户的时候才会使用消息驱动bean。换句话说,消息驱动bean可以监听来自JMS消息服务的消息。客户绝对不会直接调用消息驱动bean;要想让消息驱动做点什么事情,客户必须向一个消息服务发出一条消息,然后,JMS提供者和EJB容器协作,把消息发送给消息驱动EJB。这说明,消息驱动bean没有相应的EJBObject,因为服务器会从消息服务直接得到客户请求,而不是当客户向bean发出调用时截获客户请求。消息Bean生存于EJB容器之内,也从EJB容器的各种服务受益,如事务、安全以及并发控制等。当需要异步地接收调用请求(消息)时,使用消息Bean。它的特点是

没有Home接口和远程接口;
只有一个业务方法:onMessage()。这个方法接收一个JMS消息;
没有任何返回值;
不能发放任何异常给客户端;但可以发出系统异常,通知容器进行相应的处理;

c.会话Bean:

几乎各种后端服务都可以(而且通常应该)使用会话bean来实现。实体bean表示的是一个东西,而会话bean通常表示一个过程。当你想到实体bean的时候,应该能想到这是一个名词,而在考虑会话bean时,脑海里应该有动词的概念。购物就是一个典型的会话bean例子,信用卡处理系统也可以算作一个会话bean。会话bean可以(在部署时)标记为无状态(stateless)或者有状态(stateful)。有状态bean可以记住方法调用之间的会话状态(指“客户特定的状态”,典型的例子就是购物车。假如你去买东西,推上一个购物车,放一件商品进去,然后再放第二个商品的时候,你发现头一个商品不翼而飞了,如果是这样,你肯定不爽),而无状态bean对于方法调用之间的客户情况则是什么也记不住。如果一个服务不需要客户和服务之间有一个连续的会话,此时无状态bean就很适用。这并不是说客户不能持续地调用无状态bean的方法,只是客户不能指望这个无状态bean记住以前的方法调用的情况。它是一种非持久性的Bean,相对生命较短,一般与客户同步,存在于客户应用与应用服务器交互的时间段内;其中的数据不保存在数据库中。

有状态和无状态会话bean的本质区别是它们的生命期。

  • 无状态会话bean 将不保存该bean使用者的状态,它使用的是单例模式 , 在ejb容器中只有一个实例存在 ,主要处理系统中的业务逻辑部分。
  • 有状态会话bean 将保存该bean使用者的状态,就像web程序中每一个用户分配一个session一样, 对不同使用者生成不同的实例,  并维持该使用者操作的状态, 到ejb 容器销毁该bean 。 使用处理想购物车类的业务操作。

对比:会话Bean vs. 实体Bean

会话bean 实体bean
表示一个业务过程 表示业务数据
每一客户一个实例 在多个客户间共享实例
Short-lived:与客户生命同步 Long-lived:与数据库中数据同步
暂态的 持久的
服务器崩溃后丢失 服务器崩溃后可重构
可以是事务性的 总是事务性的

 

6.EJB构件的实现步骤

  • 定义远程接口( EJBObject接口)
  • 定义Home接口
  • 实现Bean的实现类,实现远程接口
  • 编译远程接口、Home接口、bean实现类
  • 创建部署描述符(Deploy Descriptor:说明构件的配置要求,如事务、持久化和安全等方面)
  • 将以上三个文件与部署描述符文件打包为一个ejb-jar文件
  • 部署EJB构件:将Jar文件发布到EJB应用服务器环境中,测试各层的连接情况;

7.EJB容器

a.定义:一个管理一个或多个EJB类/实例的抽象。它通过规范中定义的接口来提供EJB类所需的服务。容器厂商也可以在容器或服务器中提供额外服务的接口。理论上讲,一个EJB容器可以包含任何数量的enterprise bean。一个EJB容器可以作为一物理的实体实现,也可以作为一个逻辑的实体实现,能够跨越任意数目的系统和进程进行复制和分布。容器可以管理对象的生命周期、对象与对象之间的依赖关系,可以使用一个配置文件(通常是XML),在上面定义好对象的名称、如何产生(Prototype 方式或Singleton 方式)、哪个对象产生之后必须设定成为某个对象的属性等,在启动容器之后,所有的对象都可以直接取用,不用编写任何一行程序代码来产生对象,或是建立对象与对象之间的依赖关系。

网友的观点(未知正确与否):

换个更直白点的说明方式:容器是一个Java 所编写的程序,原先必须自行编写程序以管理对象关系,现在容器都会自动帮忙作好。
比如:你想喝水,现在有一个茶壶,你就知道可以从茶壶嘴倒出水来 




容器本身是一个组件,与其他组件的区别是——他可以存放其他的组件,也就是说其他的组件可以放在他的上面。







b.责任:

image

Remote Client Connectivity:EJB容器提供的最基本的服务,该服务支持远端的客户应用访问enterprise bean;EJB容器使用JNDI服务将enterprise bean的home interface注册到一个目录服务中;客户应用通过JNDI服务接口获取特定enterprise bean的home接口的引用。

Life Cycle Management:基于生命周期管理服务,enterprise bean可以为来自多个客户应用的请求服务。在处理来自多个客户应用的请求时,EJB容器会改变enterprise bean的状态。Enterprise bean的状态表明EJB容器中是否存在enterprise bean的实例。

Transaction Management:事务提供一个“all-or-nothing”的简单模型,如所有对象成功更新,所有工作成功提交,或者一个对象失败而整个工作回滚。bean的客户可以以两种方式驱动事务:

使用容器管理事务:EJB容器设置事务的边界,自动管理客户程序与enterprise bean交互的开始与结束; 一般,容器在EJB方法开始之前开始一个事务,而方法就在事务提交之后立即退出; 在容器管理的事务中,可以同时使用会话Bean和实体Bean;

使用Bean管理的事务:容器管理事务有一个限制:当方法正在执行时,要么关联一个独立的事务,要么什么都不关联。使用Bean管理事务能获得对事务更精确的控制。编码Bean管理的事务时,可使用JDBC和JTA事务;只适用于会话Bean。

Security Management:只有授权用户才能够访问EJB应用中的enterprise bean。具有安全要求的EJB的客户端需要进行认证和授权。认证在EJB方法调用之前的某个时间执行,授权发生在EJB的方法调用期间。EJB规范不涉及认证,跟应用服务器的具体实现以及客户端代码相关;

Persistence Management:持久性管理管理entity bean数据的存储与获取。EJB容器提供持久性管理所采用的机制是与具体的厂商相关的。

Resource  Management:资源管理服务管理大量的enterprise bean,这些bean在处理客户应用的请求时需要用到资源,将这些资源在大量的enterprise bean之间共享。

 

8.EJB服务器

管理一个或多个EJB容器的进程或应用程序,并提供对系统服务的访问。EJB服务器也可以提供厂商自己的特性,如优化的数据库访问接口,对其他服务(如CORBA服务)的访问。一个EJB服务器必须提供对可访问JNDI的名字服务和事务服务支持。

image  

 

9.EJB的生命周期

1 session Bean (有状态)
有状态会话Bean实例有三种状态,不存在,就绪,和钝化。
lifetime
客户端调用home接口的create 方法,ejb容器实例化一个Bean并调用setSesssionContext

ejbCreate方法,使得Bean处于就绪状态。然后客户就可以使用其商业方法了。ejb容器对Bean的生命周期

进行管理,一般会对最少使用的EJB进行钝化,当客户在使用这个EJB时,容器会进行激活,这个过程对客

户来说是透明的。当用户调用remove方法,容器调用ejbRemove方法,ejb生命周期结束.
无状态会话Bean实例就两种状态,不存在和就绪.
lifetime

客户端调用home接口的create方法,如果不存在可用的实例.jb容器实例化一个Bean并调用

setSesssionContext ejbCreate方法.当客户调用remove方法之后,ejb容器则调用ejbRemove的方法,
ejb生命周期结束.

2 实体bean
实体bean有三种状态,不存在,在pool中,就绪
lifetime

ejb容器创建实例时调用setEntityContext,把容器的上下文传到bean组件中.实例化之后bean

会移到池中,此时ejb没有和任何的实体对象进行关联,所有的bean实例是一样,容器会指派它和具体的

实体标示关联,进入就绪状态。有两种方法使得一个实体bean从池化进入到就绪状态,一是客户端使用

create方法,使得ejb容器调用ejbCreate and ejbPostCreate 方法,二是容器调用ejbActivate 方法,

这对客户来说是透明的,只有当实体bean处于就绪状态时,才能调用其商业方法。同样如果实体bean要从

就绪进行池化也有两种方法,一是客户端调用remove方法,容器调用ejbRemove;二是容器ejbPassivate方法。
bmp和cmp,在bean实例从池化到就绪时,对于bmp的实体bean,容器不会自动设置primary key.因此ejbCreate and ejbActivate 需要获得这个primary key ,如果这个key非法,ejbLoad and ejbStore methods 不能同步实体变量到数据库。ejbCreate 通过参数传入,ejbActivate 通过id = (String)context.getPrimaryKey();在pool状态,这些需要持久化的实体变量则不需要,在ejbPasssivate 中把它赋值null。unsetEntityContext,
bean生命周期结束的时候,调用
3 mdb 消息bean
消息bean就两种状态:不存在和就绪
lifetime

就像sessionless session bean,容器在实例化bean的时候,调用setMessageDrivenContext,ebjCreate. 调用ejbRemove方法结束生命周期。当消息到达的时候Onmessage方法。因此可以mdb是一种jms客户端企业级组件。

 

10.EJB 与 CORBA

EJB的许多概念来自于CORBA;EJB和J2EE为传统的中间件编程带来了一个以Java为中心的、基于组件的方法,这是一个适于快速应用程序开发的结构;CORBA组件模型(CCM)增加了CORBA的组建特性,CORBA组件非常类似于EJB组件。

EJB需要与CORBA集成,从而使得不同语言编写的客户端能够调用EJB提供的服务;CORBA常常是一种居于EJB级别之下的功能技术(enabling technology),许多EJB服务器厂商将EJB产品放在一个CORBA框架的顶部;

 

下边是转载于DW的一篇文字的一部分:

 

CORBA 和 EJB 技术的关系

 

公用对象请求代理程序体系结构 (CORBA) 为分布式对象的平台中立和语言中立的计算环境奠定了基础。在 CORBA 环境中,功能驻留于对象之中,而客户机可通过对象请求代理程序 (ORB) 访问这些对象。完整的 CORBA 实现提供 ORB,外加称为 CORBA 对象服务和 CORBA 公用工具的几个运行时服务。也可只提供 ORB,不提供相关联的对象服务和公用工具(例如,IBM 就提供这样的两种独立 ORB)。实现基本 ORB 功能的软件称为 ORB 核心 。为了支持语言无关性,CORBA 应用程序是用接口定义语言 (IDL) 编写的。该语言在语法上类似于 C++,但不包含语义:IDL 中指定的操作是操作接口,而不是操作实现。由于它对多种平台和多种语言的支持,以及源自其分布式特征的可伸缩性,CORBA 非常适合于管理企业规模的信息系统。

设计 EJB 规范也是为了支持企业信息系统。这样说来,CORBA 是一个竞争者吗?根据 Frequently Asked Questions for Enterprise JavaBeans ,答案是否定的:

“实际上,EJB 技术很好地补充了 CORBA。CORBA 提供了一个强大的基于标准的基础结构,可在此结构之上构建 EJB 服务器。EJB 技术使得在 CORBA 基础结构的顶层构建应用程序变得更为容易。”( Enterprise JavaBeans 常见问题解答

虽然 EJB 规范和 CORBA 规范说明的是不同的技术,但 EJB 实现目前利用 CORBA 技术的某些方面。一个例子就是 RMI/IIOP。EJB 规范要求 EJB 组件及其容器使用 Remote Method Invocation (RMI) 技术,实现分布式对象之间的方法调用。 RMI 规定远程方法的语法和语义,但并不规定应使用何种传输协议提供网络连接。CORBA Internet 对象请求代理程序间协议 (IIOP) 基本上定义了通过 TCP/IP 传输 CORBA 消息的一种方法。开发使用 IIOP 消息形式交换 RMI 数据的 EJB 实现,说明了 EJB 应用程序怎样才能有效地使用 CORBA 技术的各部分。这种网络也支持与 CORBA 应用程序的互操作性,后者使用 IIOP 发送本地 CORBA 消息,与 RMI 无关。IBM 的 EJB 实现,即 WebSphere Application Server,优化了 IIOP 的使用,方法是,弄清楚分布式对象何时驻留在同一台服务器上,并且只在对象确实在远程时才调用 IIOP。

为了方便既并入 EJB 技术,又并入 CORBA 技术的企业系统的开发,Sun Microsystems 在 EJB 规范和 CORBA 之间创建了一种映射。将 EJB 体系结构映射到 CORBA,影响到 EJB 技术的几个方面,包括对象分布、命名和事务。CORBA 映射的主要目的是,保证不同厂商构建的 EJB 服务器之间的互操作性。互操作性提供以下好处:

  • CORBA 客户机可以访问部署在基于 CORBA 的 EJB 服务器上的 EJB 组件
  • 客户机程序在事务中可以将对 CORBA 对象的调用,与对企业级 bean 的调用混合在一起
  • 事务可以跨多个 bean,而这些 bean 又位于来自不同厂商的基于 CORBA 的多台 EJB 服务器上
  • 使用来自某个厂商的 ORB 的客户机,可以访问另一个厂商基于 CORBA 的 EJB 服务器上的 bean

对于要访问 EJB 组件的 CORBA 客户机来说,bean 接口被映射到 IDL。例如,可将股票交易 bean 中定义的 buy()sell() 方法,指定为 IDL 文件中的 CORBA 操作。非 bean 的 CORBA 客户机,如 C++ 客户机,可以访问这个 bean,并用标准 CORBA 调用来调用 bean 的方法。如果容器使用 IIOP 作为它的分布式对象协议,则该容器的职责是,生成与企业级 bean 及其接口对应的 IDL。

EJB 命名服务,它以“CORBA 对象服务”命名服务为基础,使 EJB 组件可用于 CORBA 客户机。Java Naming and Directory Interface (JNDI) 可提供到 CORBA 命名服务的接口,同时,客户机既可以通过 JNDI 调用间接访问基础命名服务,也可以通过“CORBA 对象服务” (COS) 命名 API 直接访问该服务。

EJB 事务支持依赖于 CORBA Transaction Service,即 Object Transaction Service (OTS)。Java Transaction Service (JTS) 代表 OTS 的 Java 绑定,它是语言中立的。基于 CORBA 的 EJB 容器必须识别 CORBA 客户机通过 OTS 接口发出的事务边界,以及 EJB 应用程序通过 Java Transaction API (JTA) 接口发出的事务,JTA 是到 JTS 的应用程序级接口。JTA 还代表 Open Group XA 接口的 Java 绑定,以便将应用程序资源连接到外部事务管理器。JIA 中含存的 javax.transaction.UserTransaction 接口,为事务边界的应用程序级控制提供 API。UserTransaction 接口,既可由其事务属性设置为 TX_BEAN_MANAGED 的 bean 使用,以可由 Java 客户机使用。

 

作者:gnuhpc
出处:http://www.cnblogs.com/gnuhpc/

posted @ 2013-01-04 14:30  gnuhpc  阅读(730)  评论(0编辑  收藏  举报