我正在阅读有关无状态会话bean的内容,无法理解它的用法。
摘自下面的sun教程
“..因为无状态会话bean可以支持多个客户端,所以它们可以为需要大量客户端的应用程序提供更好的可扩展性”
使用无状态会话bean的位置?什么样的应用程序使用它?
在“无状态会话bean”出现之前使用了什么机制来支持类似上下文中的多个客户端?
有人可以提供一些细节吗?
谢谢你!答案 0 :(得分:5)
说实话,很难找到任何合理的SLSB用例。由于它们没有任何状态(如名称所示),因此它们本身应该是线程安全的。即使它们被容器汇集在一起。
另一方面,很有可能将它们用作安全的临时存储,因为它们保证是线程安全的(由于池),您不需要任何同步或线程安全的集合。 但请考虑以下pseude-code:
@Stateless
public class Slsb {
private int counter;
public void increment() {
++counter;
}
public int getCounter() {
return counter;
}
}
客户端:
@Resource
private Slsb slsb;
public void clientMethod() {
slsb.increment();
slsb.increment();
slsb.getCounter(); //???
}
这段代码(尽管它粗俗)完全没问题,例如它不需要AtomicInteger
。
您期望得到什么结果?实际上,任何非负值都是可能的......对slsb
的任何调用可能由Slsb
的不同实例提供,同时您的(以前使用过的)实例可能已用于为不同的客户提供服务。结论:在SLSB中存储状态是错误的,但由于某些原因,SLSB被汇集以避免在更改状态时出现线程问题(?!?)。 Personally我更喜欢单身人士服务(类似Spring),我从来没有得到过SLSB的想法。是的,我知道EJB 3.1中的单例EJB。
答案 1 :(得分:5)
在使用EJB 3.0之后,我认为无状态会话bean可以完成Enterprise Bean环境。他们确实在那里为您的其他业务逻辑设置Facade。人们经常建议SLSB是线程安全的,但这至少可以说是误导。
当他们的代码路径包括调用非线程安全代码(例如,共享的非线程安全缓存)时,它们肯定不是线程安全的.SSLSLB给出的唯一保证是单个SLSB实例最多被同一个线程使用时间。这基本上归结为SLSB具有同步方法访问权限,并且将有多个实例来服务客户端调用。但是,从这些多个实例中使用SLSB方法从共享的非线程安全类调用代码仍然可能造成严重破坏,并且会使有问题的SLSB呈现非线程安全。
由于EE上下文(事务,安全资源等)已经绑定到线程,我认为不需要SLSB而不是Spring Singletons。它们确实在仅EJB应用程序中补充Statefull会话bean。
在我看来,他们使用SLSB选择的路由以及EJB 3.1的新锁并发设置是试图让程序员愚蠢并让Mighty Container满足您的需求。帮自己一个忙,去阅读Java Concurrency in Practice,并开始使用单例和库存java线程并发结构。 (同步,易变,并发收集等)
答案 2 :(得分:2)
第一个无状态会话bean(SLSB)是服务器端技术 - 例如,您不在swing代码中使用它们。
但它们例如用作连接到中央服务器的许多客户端的“Facade”。 SLSB包含业务逻辑,然后可以例如打电话到数据库。
由于可以合并SLSB,因此每个客户端不需要一个SLSB,而每个客户端只需要一个SLSB。当不使用SLSB时,它会被放回池中,然后可以用于下一个客户端。
由于SLSB在一个容器中“托管”,它们是线程安全的,并且容器为您提供了大量的提升:事务,安全性,资源注入等。
答案 3 :(得分:2)
与大多数答案相反,让你相信,无国籍与班级本身的线索安全无关。这绝对不是@Stateless
的主要目标。开发人员本身仍然负责表示@Stateless
EJB的类没有声明任何实例变量(即没有状态)。容器不对该部分负责。基本上,开发人员必须说“Hey容器,这里是一个无状态的业务服务类,我将使用@Stateless
注释它,以便您可以将它用作无状态EJB”,因此不是相反的方式。 / p>
如果你想要状态,那么使用@Stateful
,每次客户端获取它时都会重新创建它(因此,如果客户端是一个视图范围的JSF托管bean,那么EJB将会活得很长那个bean,或者如果客户端是例如一个会话范围的CDI托管bean,那么EJB将与该bean一样长寿等。或者,使用@Singleton
,它基本上是应用程序作用域,实际上是线程锁定的。
无国籍和汇集更多与交易的安全性有关。您可能已经知道,@Stateless
上的单个方法调用默认计为单个完整事务。但是,由于所有敏感的前后处理工作,该事务反过来需要对特定EJB实例进行线程锁定。因此,EJB基本上可以阻止所有其他想要调用相同方法的客户端,直到提交事务为止。 那正是他们按需克隆和汇集的原因。
请注意,@Singleton
未合并,默认情况下实际上是线程锁定的。您应该现在明白,当{(1)用作“无状态EJB”时,@Singleton
绝对不会比@Stateless
快。另见a.o. Java EE 7 tutorial "Managing concurrent access in a singleton session bean"
答案 4 :(得分:1)
从非EJB技术特定的角度来看,无状态会话Bean是基础设施代码,显然不会保留任何状态,但会传递具有状态的对象。在EJB之外的其他实现中,状态可由您的有状态会话Bean或域POJO查看。正如上面的评论所述,它是您业务层的入口点或外观。
在java Web应用程序中,您可以按层设计,例如Controller,Service类(SLSB或只是普通的Java interace),然后是DAO或其他任何调用数据库/后端。
但是,EJB可以自动提升锅炉板,例如交易,安全等。答案 5 :(得分:1)
无状态对象将使您能够从客户端松散地耦合自己,从而允许您轻松扩展。
无状态会话bean(SLB)是服务器端(EJB)组件,用于抽象业务逻辑。由于无状态的本质,您可以轻松地将SLB部署在不在同一JVM之上的不同容器中。根据您的要求,您可以拥有一个或多个运行这些bean的容器。