Jakarta ee 何时在无状态会话bean上使用有状态会话bean?

Jakarta ee 何时在无状态会话bean上使用有状态会话bean?,jakarta-ee,ejb,stateless-session-bean,stateful-session-bean,Jakarta Ee,Ejb,Stateless Session Bean,Stateful Session Bean,有状态会话bean的定义如下: 有状态会话bean对象的状态由值组成 它的实例变量。在有状态会话bean中,实例 变量表示唯一客户端bean会话的状态。因为 客户机与其bean交互(“对话”),这种状态通常是 被称为对话状态 无状态会话bean的定义如下: 无状态会话bean无状态会话bean不维护 与客户的对话状态。当客户端调用 方法,该bean的实例变量可能包含 特定于该客户端的状态,但仅在 调用。方法完成后,将显示特定于客户端的状态 不应保留。但是,客户端可能会更改 池化无状态bean中的

有状态会话bean的定义如下:

有状态会话bean对象的状态由值组成 它的实例变量。在有状态会话bean中,实例 变量表示唯一客户端bean会话的状态。因为 客户机与其bean交互(“对话”),这种状态通常是 被称为对话状态

无状态会话bean的定义如下:

无状态会话bean无状态会话bean不维护 与客户的对话状态。当客户端调用 方法,该bean的实例变量可能包含 特定于该客户端的状态,但仅在 调用。方法完成后,将显示特定于客户端的状态 不应保留。但是,客户端可能会更改 池化无状态bean中的实例变量,并且此状态保持不变 转到池化无状态bean的下一次调用。除了 在方法调用期间,无状态bean的所有实例都是 等效,允许EJB容器将实例分配给任何 客户也就是说,应该应用无状态会话bean的状态 接受所有客户

与有状态会话bean相比,使用无状态会话bean的优势如下:

因为无状态会话bean可以支持多个客户端,所以它们可以 为需要大量数据的应用程序提供更好的可扩展性 客户群。通常,应用程序需要较少的无状态会话 bean要比有状态会话bean支持相同数量的 客户

所以我想到的问题是,何时应该使用有状态会话bean?根据我对此事的天真理解,应该尽可能坚持使用无状态会话bean

应该在哪些候选中使用有状态会话bean?有好的例子吗


首先,您必须了解如何在服务器上创建和处理bean

对于无状态会话bean,服务器可以在池中维护不同数量的实例。每次客户端请求这样一个无状态bean时(例如通过一个方法),都会选择一个随机实例来服务该请求。这意味着,如果客户机执行两个后续请求,则无状态bean的两个不同实例可能为请求提供服务。事实上,两个请求之间没有会话状态。此外,如果客户机消失,无状态bean不会被销毁,并且可以为来自另一个客户机的下一个请求提供服务

另一方面,有状态会话bean与客户机紧密相连。每个实例都被创建并绑定到单个客户机,并且只服务于来自该特定客户机的请求。因此,如果您对一个有状态bean执行两个后续请求,那么您的请求将始终从该bean的同一实例得到服务。这意味着您可以在请求之间保持对话状态。在生命周期结束时,客户端调用remove方法,bean被销毁/准备进行垃圾收集

何时使用无状态或有状态

这主要取决于您是否要保持会话状态。例如,如果您有一个将两个数字相加并返回结果的方法,那么您将使用无状态bean,因为它是一次性操作。如果您使用其他数字再次调用此方法,则您对上一次加法的结果不再感兴趣


但是,例如,如果您想计算客户机已完成的请求数,则必须使用有状态bean。在这个场景中,了解客户机之前请求bean方法的频率很重要,因此您必须在bean中维护会话状态(例如,使用变量)。如果您在这里使用无状态bean,那么每次客户端的请求都会来自不同的bean,这会弄乱您的结果。

我认为使用有状态会话bean的最好例子是用于购物车,在购物车中存储用户想要购买的所有产品

“如果客户端消失,bean也会被破坏”。实际上,有状态会话bean不会自动销毁,除非显式调用由
@Remove
javax.ejb
)修饰的方法(甚至不需要对该方法进行编码。如果该方法由
@Remove
注释,则可以将其保留为空/空白)。如果关联的客户机忘记销毁有状态会话bean,该bean将一直挂在服务器上,直到容器本身决定使用自己的策略将其删除。我做错了吗?你当然是对的。有关bean生命周期的更多信息可在此处找到:相关: