分享

J2EE企业级开发学习笔记(9)

 liumw1203 2015-03-30

J2EE企业级开发学习笔记(9)

会话Bean

 

1、EJB几个关键概念:容器、代理模式、部署描述符

   容器:EJB是部署在容器中,而不是直接部署到应用服务器上。

   代理模式:EJB是基于代理模式,而非整体式组件,其思路是把组件分割到客户和远程对象中去。

   部署描述符:为了能自定义开发好的组件,方便地把开发和部署分开。

 

2、EJB结构:主Java类(实现类或Bean类)、两个接口(Home本地、Remote远程)。

   客户视图(子系统):

   J2EE企业级开发(9)会话Bean

   J2EE企业级开发(9)会话Bean

  内部视图:客户视图的所有组件、实现类和与之关联的关系、及用户添加到EJB设计中的任何其他类。在UML类视图中,这些类是作为标准类和视图出现的。

  即客户视图是EJB的外观视图,而内部视图则是通过完全展示UML包的内容获得的。

  J2EE企业级开发(9)会话Bean

 

3、会话Bean:

   第一种被广泛采用和普遍使用的EJB。目前主要用于客户端的交互处理低级别的状态和事务,如名称提示、客户会话等。会话Bean使用的优点:内置交易管理功能、内置状态管理功能。

 

4、会话Bean分类和特性:

   会话Bean分两类:有状态和无状态。它们决定了组件是否可以保存被称为“会话状态”的信息。会话状态指特定客户端和会话对象通话的数据。

   有状态会话Bean:能让客户端在任意一段时间内(几秒、几分钟、几小时或几天等),对特定会话对象进行操作,然后在之后的某个时间段返回并准确的获取他或她是否停止使用了同一个会话对象的信息。

   无状态会话Bean:客户端操作一个给定的会话对象,然后离开任意一段时间,在离开一瞬间就会丢弃会话对象且不会保存会话状态。如果客户端返回,就会创建一个新的会话对象,一切从头开始。

   有状态会话Bean的常用特性:创建成只被一个客户端使用;只被一个独一无二的标识符调用;保存从方法到事务的信息;通过实例钝化保存状态;可以实现会话同步。

   无状态会话Bean的常用特性:创建成可以被多个客户端使用,不过一次只能有一个客户端使用;没有独一无二的标识符,通常是Bean池的一部分;不保存从方法到事务的状态;不通过实例钝化保存状态;不能实现会话同步。

 

5、会话Bean通信状态管理:

  例子:预定飞机航班(设置用户优先选择如需要的座位数量,期望的航班时间,最喜欢的飞行路线,价格范围等,其后用户一般会提供往返时间和城市,可用于飞往国外或返航两个时间段)

  J2EE企业级开发(9)会话Bean

下面是显示了一个引导顾客出票的成功方案:(使用状态图为会话状态建模将使TravelReservations Bean 更易于理解和实现)其中setUserPrefs代表用户的优先选择,getFlightOptions代表航班的选项信息

J2EE企业级开发(9)会话Bean

 

6、实例钝化:

  钝化是EJB容器提供的,专门用于有状态会话Bean的一个有用特征。但EJB当前不在客户端事务中,且EJB服务器确定需要换出Bean,以释放一些内存或其他系统资源时,就会出现钝化。通常在下一次与客户端交互时,换出后的EJB能再次激活。有状态的会话Bean一旦被再次激活,客户端总是返回同一种独特的会话对象,同时保存会话状态以确保对象信息的安全。而无状态的会话Bean激活该对象后,每一次激活,该会话对象都会重新生成,像新的一样,同时在Bean池中,这些对象仍然处于激活状态,如果EJB服务器确定他需要释放一些资源,它只是从池中清除一些闲置的会话Bean,并有效地销毁它们,因此钝化只会破坏,由于此时确实不需要保留会话状态,所有可以这样做。

7、清理和删除会话Bean:

当会话Bean不做任何有用的工作,却占用了EJB服务器上资源的时间是不允许的,比如客户端离开Web站点去做其他事情而忘了返回、网络停机、或客户端保留有一些不重要的信息,此时EJB容器会使用Bean删除机制。

 所有类型的会话Bean都可以被删除。对于有状态的会话,如果创建会话对象的Web客户端永远也不返回,该会话就必须被销毁。对于无状态的会话,执行删除操作更多地是由于EJB服务器的特定实现(如会话Bean池未被充分利用),可以根据需要压缩会话Bean池的大小。

【注意】当客户端正在使用某个会话对象时,该对象永远也不能被删除。删除只能发生在钝化或闲置状态。

8、事务处理:

 系统通常按照ACID准则来使用事务:

 Atomic(原子性):事务必须被完全执行或完全不执行,成功完成后的事务必须被提交(数据更新),否则就重新执行整个事务。

 Consistent(一致性):如果交易失败,可以还原事务活动到先前一致的状态。

 Isolated(隔离性):在事务执行时,正在被交易访问的数据是受保护的,只有到该事务结束才能被别的过程或事务干预或访问。

 Durable(持久性):执行事务所做的更改被写进永久性数据仓库。系统崩溃也不会丢失任何以提交的交易情况下让系统还原。

9、事务分类3种方法:Begin方法、Commit方法、Rollback方法

会话Bean本质主要被设计成事务性的。

  Begin:事务开始处理

  Commit:事务成功完成并将提交给数据库。

  Rollback:事务回滚。事务由于某些原因失败,并且不能被提交,回滚可以将会话对象还原到事务开始处理时的状态。

注意:事务不能进行嵌套。

 

10、事务分类:

  (1)托管Bean式事务:部署描述符中这种设置将意味着客户端将编写它自己的事务代码,可能需要用javax.transaction.UserTransaction接口。使用理由:跨越多个业务方法有一条事务边界。

  (2)托管容器式事务:容器知道何时调用begin和commit请求,以及何时执行某些标准处理,以在必要时有效地执行还原操作。如果EJB开发人员确定在事务开始或完成后还要对其进行某些特殊的处理,可以通过SessionSynchronization接口调用特殊方法时仍能使用托管容器式事务。

 

11、SessionSynchronization接口:

    只对会话Bean有效,EJB容器会为用户执行分类调用,还能让用户在Bean类中重载下面3种方法:

afterBegin方法:在调用begin方法后立即调用afterBegin,用于正在执行的事务。该方法在真正执行其他业务方法之前执行。

beforeCompletion方法:在调用commit方法后立即调用该方法,用于正在执行的事务。该方法在commit方法真正作用于事务之前执行。这是在事务恰好完成之前,会话能决定还原事务的最后一个时刻。

afterCompletion方法:在调用commit方法后立即调用该方法,用于正在执行的事务。该方法在commit方法真正作用于事务后立即执行。它提供了一个布尔型的参数以确定commit调用是否真正执行成功。

J2EE企业级开发(9)会话Bean

注意:对于无状态会话Bean两个事务分类的限制:不允许执行SessionSynchronization接口;不保存会话状态的对象不可能允许交易跨越多个业务方法。无状态会话Bean只有在交易相对较小且简单时,才能真正成功使用。

 

12、事务属性:

   当你的EJB方法需要访问资源管理器或您需要维持EJB的一致性时,特别需要事务环境的支持。

   对于会话Bean,事务属性是与所有添加到Remote接口的业务方法一起使用的。下面列出了相关事务属性值及其含义:

NotSupported:该方法不与事务环境一起运行,如果传入一个事务环境,忽略该方法调用并将其恢复到完成状态Required:该方法要与事务环境一起运行,如果没有提供事务环境,就会在方法调用时创建并使用一个新环境。

Supported:如果在没有事务环境时调用该方法,它就像NotSupported一样工作。反之,就像Required那样运行。

RequiresNew:该方法与一个新的事务环境一起运行,该事务环境是在调用方法过程中创建并使用。如果传入一个事务环境,就忽略该方法调用,并将其恢复到完成状态。

Mandatory:该方法要与事务环境一起运行。如果不传入一个事务环境,就会抛出一个异常。

Never:该方法不与事务环境一起运行。如果提供一个事务环境,就会抛出一个异常。

 

13、会话Bean技术:

Home接口:每个会话Bean都需要提供一个Home接口,该接口可用于客户端编程,以调用基本的Bean生命周期的方法。必须至少定义一个方法,即create<METHOD>,用于创建一个会话对象的实例。METHOD可以是使用create前缀的任意方法名和任意参数组合。

  对于有状态的会话Bean:可以用任意有效个数的参数组合来定义多个create方法。

  对于无状态的会话Bean:只有一种create方法,一个方法名,且不带任何参数。

 

会话Bean的Home接口示例代码:

 package com.homedirect.ejb.control;

 import java.rmi.RemoteException;

 import javax.ejb.*;

 import com.homedirect.ejb.profile.Profile;

 public interface ControlHome extends javax.ejb.EJBHome{

   public com.homedirect.ejb.control.Control create()

    throws java.rmi.RemoteException,javax.ejb.CreateException;

}

 

Remote接口:每个会话Bean都需要提供一个Remote接口,该接口可用于客户端编程,以调用所有特定的业务方法。这些方法几乎可以使用任何方法名和参数。两种类型的会话Bean都需要一个Remote接口,它们两者的实现细节是相似的。

 

会话Bean的Remote接口示例代码:

package com.homedirect.ejb.control;

import java.rmi.RemoteException;

import javax.ejb.*;

...

import com.homedirect.ejb.profile.Profile;

 public interface Control extends javax.ejb.EJBObject{

  public Profile getProfile() throws java.rmi.RemoteException;

  public void setProfile(Profile profile)throws java.rmi.RemoteException;

  ...
  public String TransferFunds(String fromAccount,String toAccount,Long iAmount)

     throws java.rmi.RemoteException,AccountException,GenerationException;

    ...

}

 

14、实现类:

 ejbCreate<METHOD>:对于Home接口中调用的每一种create方法,在实现类中必须有有一个与之匹配。唯一区别:实现类中方法名为ejbCreate,而非create,参数也必须匹配,但是返回类型是不同的。通常只执行简单的初始化EJB的步骤。

 ejbRemove:该方法不能带任何参数,当调用某个接口remove方法或EJB容器启动对其自身的清除操作时,就会调用该方法。该方法执行任何最后的EJB清理工作——与初始化操作正好相反。

 setSessionContext:该方法必须存在,并通过EJB容器调用,以允许会话Bean在局部变量中存储会话环境信息。在大多数情况下,该方法只包含一行用于存储环境信息的代码。

 业务方法:所有Remote接口中定义的业务方法必须根据方法名和参数与Bean类中的方法精确匹配。EJB逻辑中的大部分都存在于这些方法中。访问器方法(如gets\sets)也划分到这一类方法中。

 ejbPassivate/ejbActivate:他们对所有会话Bean必须一直存在,但实际上只会对有状态的会话Bean执行这两种方法。在实例钝化或激活EJB过程中会调用这两个方法。通常这些方法是无意义的,除非往后需要钝化或激活EJB,而执行某些特殊的初始化/清理程序。

 

一个会话Bean实现类的例子:

package com.homedirect.ejb.conrol;

import java.rmi.RemoteException;

...

public class ControlEJB implements javax.ejb.SessionBean{

//EJB Context

 public javax.ejb.SessionContext EJB_Context;

 //private fields

 private Profile profile=null;

...

 //Lifecycle methods

 public void ejbCreate(){

  accountHome=LookupHome.getAccountHome();

  ...

 }

 //Other Lifecycle methods

 //Business methods

 public Profile getProfile(){

  return profile;

}

 public void setProfile(Profile profile){

   this.profile=profile;

 }

 public String TransferFunds(String fromAccount,String toAccount,long iAccount)

   throws AccountException,GeneratorException{

     //logic for TransferFunds

   }

  ...

}

 

15、为接口行为建模:

  使用Bean将如何使用的简单方法:使用状态图为接口建模和编制文档,然后通过顺序图获得一个有效的解决方案。如下例购物车的例子:

J2EE企业级开发(9)会话Bean


J2EE企业级开发(9)会话Bean

16、会话Bean的生命周期:

(1)有状态会话Bean的状态图:

J2EE企业级开发(9)会话Bean
(2)无状态会话Bean的状态图:
J2EE企业级开发(9)会话Bean

17、会话Bean常用方案,使用会话Bean请遵循如下标准步骤:

a.引用Home接口前,调用javax.rmi.PortableRemoteObject.narrow(...)方法。

b.引用Home接口:为了让期望会话对象调用期望的create方法。返回对会话的Remote接口的引用。

c.引用Remote接口:调用任意的业务方法。

d.清除EJB:在Home接口或Remote接口上调用remove方法。

(1)无状态会话Bean用法的顺序图(使用了托管容器式事务分类):

     客户端只与接口打交道,而不必知道实现类的任何细节。但接口自身改变了才会对客户端产生影响。

J2EE企业级开发(9)会话Bean
(2)有状态会话Bean用法顺序图(使用了托管容器式事务分类):

     注意:客户端在第一次响应后没有任何调用的情况下等待了较长时间后,就会引发钝化序列。

J2EE企业级开发(9)会话Bean

18、会话Bean与其他组件或类的关系:

   a.会话Bean与简单Java类关系:(调用)

   J2EE企业级开发(9)会话Bean
  b.会话Bean与JavaBeans关系:

   JavaBeans可以用作会话Bean和其他JavaBeans之间交换信息的方式。也可以将JavaBean用作一种访问会话Bean的访问函数,这就相当于为客户端提供了非常简单的接口的功能,而把EJB体系结构所有强大的功能都隐藏在简单的JavaBean下。

  c.会话Bean与Servlet关系:(依赖关系适用于无状态会话Bean,否则用单向关联更好)

  J2EE企业级开发(9)会话Bean
  d.会话Bean和Jsp(Java服务器页面)关系:

  会话Bean和JSP关系同与Servlet关系相同,只是当JSP被编译进servlet,通常也只是用于显示方面,而非嵌入详细的逻辑。一条解决之道:使用JSP调用Servlet,然后由Servlet来与会话Bean或实体Bean进行交互。

  e.会话Bean与其他会话Bean关系:

  如果会话Bean需要在一个延长的时间段内,即在业务方法之间,保存关于其他Bean的信息,合适的方法是使用一种关联(调用)关系,否则使用依赖关系就足够了。
  会话Bean-Bean关系:会话Bean链。包含一个有状态会话Bean和多个无状态会话Bean的会话Bean链是合理的。把多个有状态会话Bean栓在一起,就会发出警告,而且还原链内的失败将会消耗大量时间。

J2EE企业级开发(9)会话Bean
  f.会话Bean的继承关系:

   EJB暂无继承机制,因此不支持这种继承关系。目前的建议:把Home和Remote接口及实现类划分开,然后把它们用作创建新会话Bean的基础。

 

19、管理性能:

    企业应用中使用EJB组件虽然有很有优点,但是对企业级应用的总体性能会有一定影响。如使用Remote远程调用RMI实现接口和实现分离,其好处是易于开发分布式应用程序,缺点在于与调用一个本地对象相比,远程调用总是代价昂贵的,它要消耗更多的时间和资源。 J2EE 1.2别无选择,而J2EE 1.3则为会话Bean和实体Bean引入了本地客户端。因此如何最优化您的管理性能?准则是:把远程调用次数减至最少。实现方法:JavaBeans的使用。此外不同的应用程序服务器还提供多种不同的机制来预分配和聚集资源、调整设置和平衡服务器负荷,以设法最优化您的应用的总体性能。

    本地客户端:Remote客户端变为本地客户端;Remote接口变为本地接口;Home接口变为本地Home接口;实现两个接口的对象必须是本地客户端Java对象;这些接口上的所有方法的参数和结果都是通过引用而非值传递。

    在涉及到EJB-EJB的关系时,大多数情况也建议使用本地客户端。但EJB存在与一个不同的java归档文件中或非java实现通信时使用了不同的传输机制,则本地客户端不再有效。

    使用本地客户端的缺点是:潜在的限制了把企业级应用程序的重要部分处理分布到多个服务器上去的能力。优点:很大程度上优化了性能。

20、银行资金转账中如何标识会话Bean:

 需要考虑如下细节:

  •  为单一动作(如资金转账)负责的会话Bean,还有其他职责吗?
  •  它是一个有状态会话Bean还是无状态会话Bean?
  •  它具有哪种事务?
  •  它是使用托管容器式事务还是托管Bean式事务?

 

J2EE企业级开发(9)会话Bean

21、EJB可用作一般性开发,而会话Bean要用作特殊开发,他们两者是不同的。


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多