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


82

有状态会话Bean定义如下:

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

无状态会话Bean定义如下:

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

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

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

因此想到的问题是何时应该使用有状态会话Bean?就我对此事的幼稚理解而言,应该坚持使用无状态会话bean。

应该使用有状态会话bean的候选对象是什么?有什么好的例子吗?

会话Bean


Answers:


150

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

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

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

什么时候使用无状态或有状态?

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

但是,例如,如果您要计算客户端已完成的请求数,则必须使用有状态Bean。在这种情况下,了解客户端之前多久请求一次bean方法非常重要,因此您必须在bean中维护对话状态(例如,使用变量)。如果您在此处使用无状态Bean,则每次都会从不同的Bean服务客户端的请求,这会弄乱您的结果。


15
如果客户消失了,bean也将被销毁”。实际上,除非显式调用由@Removejavax.ejb)装饰的方法,否则有状态会话Bean不会自动销毁(该方法甚至无需进行编码。给定注释为的方法,可以简单地将其留空/空白@Remove)。如果关联的客户端忘记销毁一个有状态的会话Bean,则该Bean将一直悬在服务器上,直到容器本身决定使用自己的策略删除它为止。我做错了吗?
2014年

3
你当然是对的。有关bean生命周期的更多信息,请参见:docs.oracle.com/javaee/6/tutorial/doc/giplj.html
tobiasdenzler 2015年

48

我认为,使用有状态会话bean的最大示例是Shopping Cart,其中存储了用户想要购买的所有产品。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.