何时使用有状态会话bean而不是无状态会话bean?

89

状态会话Bean的定义如下:

状态会话Bean对象的状态由其实例变量的值组成。在状态会话Bean中,实例变量表示唯一客户端Bean会话的状态。因为客户端与其Bean交互(“交谈”),所以该状态通常称为会话状态。

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

无状态会话Bean与客户端不维护会话状态。当客户端调用状态Bean的方法时,Bean的实例变量可能包含特定于该客户端的状态,但仅在调用持续时间内有效。当方法完成时,不应保留客户端特定状态。但是,客户可以更改池化无状态Bean的实例变量的状态,并且这个状态会一直保存到下一个调用池化无状态Bean的时候。除了方法调用期间,所有无状态Bean的实例都是等效的,允许EJB容器将一个实例分配给任何客户端。也就是说,无状态会话Bean的状态应适用于所有客户端。

使用无状态会话Bean(stateless session bean)而不是有状态会话Bean(stateful session bean)的优点如下:

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

那么接下来的问题是,什么时候应该使用有状态会话Bean呢?在我尚浅的理解中,只要能使用无状态会话Bean就应该优先考虑使用。

什么情况下适合使用有状态会话Bean呢?有没有好的例子?

会话Bean


相关链接:https://dev59.com/YGox5IYBdhLWcg3w6on0 - BalusC
2个回答

163

首先,您需要了解如何在服务器上创建和处理bean。

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

另一方面,有状态会话bean与客户端密切相关。每个实例都是为单个客户端创建和绑定的,仅为该特定客户端的请求提供服务。因此,如果您对有状态bean进行两个连续请求,则您的请求将始终从bean的同一实例中提供服务。这意味着您可以在请求之间保持对话状态。在生命周期结束时,客户端调用remove方法,bean被销毁/准备进行垃圾回收。

何时使用无状态或有状态?

这主要取决于您是否想要维护对话状态。例如,如果您有一个将两个数字相加并返回结果的方法,则使用无状态bean,因为它是一次性操作。如果您再次调用此方法并使用其他数字,则不再关注先前添加的结果。

但是,如果您想要计算客户端已执行的请求数量,则必须使用有状态bean。在此场景中,重要的是要知道客户端之前多少次请求了bean方法,因此必须在bean中维护对话状态(例如,使用变量)。如果您在此处使用无状态bean,则每次都会从不同的bean为客户端服务,这会破坏您的结果。


16
如果客户端消失了,那么这个Bean也会被销毁”。实际上,只有在显式调用由@Removejavax.ejb)修饰的方法之后,状态会话Bean才会自动销毁(该方法甚至不需要编码。只需留空 / 空白即可,因为它已经被注解为@Remove)。如果相关联的客户端忘记销毁状态会话Bean,则该Bean将一直悬挂在服务器上,直到容器本身使用其自己的策略决定将其删除。我错了吗? - Tiny
3
当然,你是正确的。有关 Bean 生命周期的更多信息可以在此处找到:http://docs.oracle.com/javaee/6/tutorial/doc/giplj.html。 - tobiasdenzler

58

我认为使用有状态会话Bean(Stateful session bean)的最佳例子是购物车,可以在其中存储用户想买的所有商品。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接