【问题标题】:How does a session bean work?会话 bean 是如何工作的?
【发布时间】:2014-05-14 13:00:53
【问题描述】:
假设我在我的应用程序中部署了一个有状态会话 bean。在我的客户端应用程序中,我尝试在 JNDI 的帮助下使用这个会话 bean。在获得 bean 的存根(不是实际的 bean 本身)并初始化该 bean 的一些字段后,我尝试使用 JNDI 第二次获取该 bean。
那么我将从应用服务器获得什么 bean?它会是同一个 bean 两次,还是我将使用第二个 bean 实例?如果我将获得相同的 bean 两次,我如何从应用服务器获得相同 bean 的两个不同实例?我只是很困惑豆本身是什么。如果可能的话,提供一些资源。
【问题讨论】:
标签:
java
jakarta-ee
ejb
rmi
jndi
【解决方案1】:
假设您通过 JNDI 获得对远程 bean 实例的引用。现在,假设您在远程 bean 上调用了两个业务方法,methodA 和 methodB。
有状态 bean 和无状态 bean 之间的(主要)区别如下:
- 如果您的 bean 是无状态的,那么
methodA 和 methodB 不保证在服务器端运行在完全相同的 bean 实例上。
- 如果您的 bean 是有状态的,那么
methodA 和 methodB 保证在服务器端运行在完全相同的 bean 实例上。
从客户端,请注意,您所拥有的只是对服务器端一个不起眼的对象的引用。在那个“存根”上调用多个方法——即使它是同一个存根对象——也不能保证你将在服务器端处理完全相同的对象,除非你的 bean 是有状态的。
现在,更具体地说,是针对您的问题。您说您在服务器上部署了一个有状态 bean,并且您通过 JNDI 获得了对 bean 实例的引用。为此,您必须在 EJB 的主接口上使用create 方法。 create 方法向您返回了一个存根,该存根映射到服务器端的一个实例。
下次您在主界面上调用create 时,您将获得一个不同 存根,该存根指向服务器端的一个不同 bean。
如果您想保持对前一个 bean 的访问,那么您需要以某种方式保持对该远程对象的引用。
- 如果您使用的是 EJB 2.x,那么您不应该在任何地方“缓存”存根;相反,获取对 bean 句柄的引用并将句柄存储在某处。
- 如果您使用的是 EJB 3.x,那么您可以简单地存储对存根的引用。
【解决方案2】:
有状态会话 bean 是一个企业 bean(EJB 组件),它
充当使用它的客户端的服务器端扩展。这
有状态会话 bean 由客户端创建,仅适用于
该客户端直到客户端连接断开或 bean
明确删除。
这意味着,对于同一个客户端,无论您要从服务器获取多少次,都必须返回相同的实例。否则,你不能依赖国家。
另请参阅Oracle documentation。