===================================
提纲:
===================================
一、概述
二、无状态会话bean
三、有状态会话bean
四、客户端接口
4.1 remote接口
4.2 home接口
五、实例
5.1 有状态会话bean
5.2 home接口
5.3 remote接口
5.4 部署描述器
5.5 客户程序
5.6 运行
===================================
正文:
===================================
一、概述
在企业级应用系统内,会话bean是一种代表客户程序执行操作的ejb。对于ejb客户程序来说,会话bean常常起着入口点或“前线”ejb的作用。ejb客户程序通过与会话bean的交互,从企业应用系统获取它们想要利用的功能或服务。
正如其名字所示,会话bean类似于一个交互式的会话。会话bean是不共享的,正如交互式会话只能有一个用户,而且会话bean也不具备持久化的特点(即它的数据不保存到数据库)。一旦客户程序结束运行,会话bean也就不再关联到客户程序。
会话bean有两种类型:有状态会话bean(stateful session bean),无状态会话bean(stateless session bean)。
有状态会话bean
对象的状态由实例变量的值描述。对于有状态会话bean,实例变量描述了客户程序与bean的会话的状态。鉴于客户程序与bean的交互关系,bean的状态信息通常称为会话状态。
在客户程序与bean交互期间,状态信息一直有效。如果客户程序运行结束或拆除了bean,则会话结束,状态信息也不再保留。然而,状态信息的这种临时性并不成为问题,因为当客户程序与bean之间的会话终止,状态信息也就没有必要再保存了。
无状态会话bean
无状态会话bean不为特定的客户程序保留会话状态。客户程序调用无状态bean的方法时,bean的实例变量可以包含状态信息,但状态信息仅在该次调用期间有效。当方法调用结束,状态信息也就不再保留。除了bean方法正在执行的时间之外,所有无状态bean的实例都是等价的,这使得ejb容器能够把bean的实例分配给任意客户程序。
由于无状态会话bean支持多个客户程序,对于那些客户程序数量很大的应用,无状态会话bean具有更好的可伸缩性。一般地,对于支持同样数量的客户程序来说,应用需要的无状态会话bean数量少于有状态会话bean数量。
一些时候,ejb容器可能把有状态会话bean保存到第二级存储设备,但容器永远不会保存无状态会话bean。因此,无状态会话bean比有状态会话bean有着更好的性能。
一般地,在下列情形下,我们可以使用会话bean:
在任意时刻只有一个客户程序访问bean的实例。
bean的状态无需持久化,只在短期内生存(比如几个小时)。
如果满足任意以下条件,使用有状态会话bean比较合适:
bean的状态描述了bean与特定客户程序的交互。
bean需要保留有关客户程序的信息,且保留期限必须跨越多次方法调用。
bean担负着客户程序到应用其他组件之间的中间人的角色,为客户程序提供一个简化的服务视图。
bean管理着多个ejb的工作流程。
为提高性能,当bean具有任意下面的特征之一时,最好选用无状态会话bean:
bean的状态信息不包含任何针对特定客户程序的数据。
bean从数据库提取一组客户程序经常使用的只读数据。例如,bean从数据库提取出本月销售的产品信息。
二、无状态会话bean
无状态会话bean不在ejb之内保留面向特定客户程序的状态信息,但这并不意味着这类ejb不在本身的域或关联的对象里面保留任何状态数据,其真实含义是,这类bean保持的状态信息不是为特定ejb客户程序下一次访问或使用而保留。
这种特点使得ejb容器能够更高效、更灵活地管理无状态会话bean。在任意时刻,任意一个客户程序可以使用容器创建的任意一个无状态会话bean的实例。因此,容器可以为这类实例构造一个缓冲池,根据客户程序的需求从缓冲池分配bean的实例,无需顾虑哪一个实例属于哪一个客户程序。此外,必要时容器能够方便地创建或拆除bean的实例,根据应用规模和资源情况作出调整。虽然无状态会话bean可能拥有状态信息,但在两次对bean实例的连续调用之间,开发者不能假定这些状态信息的合法性。
图一显示了无状态会话bean组件构造的基本体系结构。
[[the no.1 picture.]]
位于图一顶端的是javax.ejb.enterprisebean接口,它是所有ejb的基础接口。从enterprisebean接口派生出了javax.ejb.sessionbean接口。公用的、非最终的、非抽象的无状态会话ejb,比如图一显示的mystatelesssessionejbean,必须实现javax.ejb.sessionbean接口。无状态会话ejb实现公用的、非最终的、非抽象的业务方法,比如图一显示的somemethod()和anothermethod()。实现会话bean的类必须有一个公用的、不带参数的构造函数,且不应该实现finalize()方法。
无状态会话bean上定义的setsessioncontext()方法用来把一个sessioncontext的实例传入ejb,它也是sessionbean接口上定义的第一个由容器调用的方法。sessioncontext对象封装了一个ejb会话容器上下文的接口,支持会话bean的实例访问容器提供的运行时会话上下文。在bean实例生存期间,会话上下文将一直保持与bean实例的关联。
对于无状态会话bean,尽管在sessionbean接口中没有定义ejbcreate()方法,但它是一个关键的操作。无状态会话bean必须定义一个返回值为void的ejbcreate()方法,容器准备创建bean的实例时将调用这个方法。容器决定创建bean的实例可能是因为它要构造一个bean实例的缓冲池,也有可能是因为它接收到了客户程序的请求。因此,ejbcreate()方法属于一种由ejb实现的特殊的构造函数或初始化方法。
当容器决定不让bean的实例继续处理客户程序的请求时,它就会调用bean实例的ejbremove()方法。对于无状态会话bean,何时调用bean实例的ejbremove()方法由容器单独决定,不受ejb客户程序的任何影响。
三、有状态会话bean
有状态会话bean在ejb之内保留的状态信息与ejb客户程序有着明确的关系。有状态会话bean的状态信息是指保存在bean实例的域里面的数据,以及bean实例持有的各种对象里面的数据。当一个ejb客户程序在某一时刻访问一个有状态会话bean,且改变了该bean实例的状态,则状态信息将被保留,下一次bean再次被访问时,bean的实例将使用原先保存的状态信息。
对于有状态会话bean,容器承担着更多的bean管理方面的责任。实际上,客户程序创建或拆除有状态会话bean直接关系到服务器端bean实例的创建和拆除。此外,当资源紧张时,容器可能决定把一个或者多个有状态会话bean串行化(也就是钝化)到持久性存储设备,一旦资源重新空闲,或出现了客户程序的请求,被钝化的bean必须激活并转入活动内存。因此,设计有状态会话bean时,开发者必须考虑更多的问题。
图二显示了有状态会话bean组件构造的基本体系结构。
[[the no.2 picture.]]
公用的、非最终的、非抽象的有状态会话bean,如图二显示的mystatefulsessionejbean,必须实现sessionbean接口。sessionbean接口从enterprisebean接口派生。另外,有状态会话ejb也实现公用的、非最终的、非抽象的业务方法,比如图二显示的somemethod()方法和anothermethod()方法。实现会话bean的类必须有一个公用的、不带参数的构造方法,且不应实现finalize()方法。最后,有状态会话bean可以实现javax.ejb.sessionsynchronization接口,使得bean能够收到某些事务管理方面的事件通知,但这是可选的。
由于状态信息对于有状态会话bean的重要性,创建bean时初始化操作也很重要。有状态会话bean可以定义一个或者多个ejbcreate(...)方法,这些方法带有零个或者多个输入参数,方法的返回值类型是void。传递给这类方法的具体参数由应用本身决定,但方法的名字必须是ejbcreate()。与无状态会话bean上的ejbcreate()调用不同,有状态会话bean的ejbcreate()方法绑定到ejb客户程序,ejb客户程序将一直使用特定的ejb实例。另外也请注意,正如对于无状态会话bean,在调用任何ejbcreate()方法之前,容器将调用有状态会话bean的setsessioncontext()方法。
如果有状态会话bean的ejbremove()方法被调用,则表明对应的客户程序已经决定不让该bean继续处理请求。另外,会话最大超时时间到达时,容器也会调用bean的ejbremove()方法。
设计有状态会话bean的过程中,有时最重要的事情就是bean的钝化和激活操作。正如前面所指出的,容器钝化某个bean时,它将串行化bean的内容,并把这些信息写入某个持久性存储设备。容器之所以钝化bean是因为内存资源不足。通常,容器通过某种形式的“最近最少使用”算法确定应该钝化哪些bean的实例(当然,实际所用的算法由具体的平台决定)。
在钝化bean的实例之前,容器会调用bean的ejbpassivate()方法,有状态会话bean必须实现这个方法。在ejbpassivate()方法中,我们应该清除所有不能串行化和持久化的资源,比如数据库连接和打开的文件句柄。ejbpassivate()方法执行完毕之后,所有仍未关闭的对象应该能够被容器钝化。
如果出现了对已经
闽公网安备 35060202000074号