为什么无状态会话bean?

Sur*_*rez 6 ejb stateless-session-bean java-ee

我正在阅读无状态会话bean,无法理解它的用法.

摘自下面的太阳教程

"..因为无状态会话bean可以支持多个客户端,它们可以为需要大量客户端的应用程序提供更好的可伸缩性"

在哪里使用无状态会话bean?什么样的应用程序使用它?

在"无状态会话bean"出现之前使用了什么机制来支持类似上下文中的多个客户端?

有人可以提供一些细节吗?

谢谢!

Tom*_*icz 5

说实话,很难找到任何合理的SLSB用例.由于它们没有任何状态(如名称所示),因此它们本身应该是线程安全的.即使它们被容器汇集在一起​​.

另一方面,它很有可能将它们用作安全的临时存储,因为它们保证是线程安全的(由于池),您不需要任何同步或线程安全的集合.但请考虑以下pseude-code:

@Stateless
public class Slsb {
  private int counter;

  public void increment() {
    ++counter;
  }

  public int getCounter() {
    return counter;
  }
}
Run Code Online (Sandbox Code Playgroud)

客户端:

@Resource
private Slsb slsb;

public void clientMethod() {
  slsb.increment();
  slsb.increment();
  slsb.getCounter();  //???
}
Run Code Online (Sandbox Code Playgroud)

这段代码(尽管它粗俗)完全没问题,但并不需要AtomicInteger.

你期望得到什么结果?实际上,任何非负值都是可能的......任何调用都slsb可能由不同的实例提供服务Slsb,同时您的(以前使用过的)实例可能已用于为不同的客户端提供服务.结论:在SLSB中存储状态是错误的,但由于某些原因,SLSB被汇集以避免在更改状态时出现线程问题(?!?).就个人而言,我更喜欢单身人士服务(类似Spring),我从来没有得到过SLSB的想法.是的,我知道EJB 3.1中的单例EJB.

  • `因为它们保证是线程安全的(感谢池化)` 不,它们不是。例如,请参阅 EJB 3.1 规范,4.3.10.2 无状态会话 Bean:“由于无状态会话 Bean 实例通常是池化的...”只是“通常池化”。默认情况下,Wildfly 8-9 不池化 SLSB,而 Wildfly 10 则池化。 (2认同)

小智 5

在使用EJB 3.0之后,我认为无状态会话bean可以完成Enterprise Bean环境.他们确实在那里为您的其他业务逻辑设置Facade.人们经常建议SLSB是线程安全的,但这至少可以说是误导.

当它们的代码路径包括调用非线程安全代码(例如,共享的非线程安全缓存)时,它们绝对不是线程安全的.SLSLB给出的唯一保证是同一个线程最多只能使用一个SLSB实例.这基本上归结为SLSB具有同步方法访问权限,并且将有多个实例来服务客户端调用.但是,从这些多个实例中使用SLSB方法从共享的非线程安全类调用代码仍然可能造成严重破坏并且会使有问题的SLSB呈现非线程安全.

由于EE上下文(事务,安全资源等)已经绑定到线程,我认为不需要SLSB而不是Spring Singletons.它们在仅EJB应用程序中补充Statefull会话bean.

在我看来,他们使用SLSB选择的路由以及EJB 3.1的新锁并发设置是试图让程序员愚蠢并让Mighty Container满足您的需求.帮自己一个忙,去阅读Java Concurrency in Practice,并开始使用单例和库存java线程并发结构.(同步,易变,并发收集等)