我正在阅读有关无状态会话 bean 的信息,但无法理解它的用途。
摘自下面的太阳教程
“..因为无状态会话 bean 可以支持多个客户端,它们可以为需要大量客户端的应用程序提供更好的可扩展性”
在哪里使用无状态会话 bean?什么样的应用程序使用它?
在“无状态会话 bean”出现之前,使用什么机制来支持类似上下文中的多个客户端?
谁能提供一些细节?
谢谢你!
我正在阅读有关无状态会话 bean 的信息,但无法理解它的用途。
摘自下面的太阳教程
“..因为无状态会话 bean 可以支持多个客户端,它们可以为需要大量客户端的应用程序提供更好的可扩展性”
在哪里使用无状态会话 bean?什么样的应用程序使用它?
在“无状态会话 bean”出现之前,使用什么机制来支持类似上下文中的多个客户端?
谁能提供一些细节?
谢谢你!
老实说,很难找到任何合理的 SLSB 用例。由于它们不持有任何状态(正如其名称所强加的),它们本质上应该是线程安全的。即使它们被容器池化。
另一方面,将它们用作安全的临时存储是很诱人的,因为它们保证是线程安全的(感谢池),您不需要任何同步或线程安全的集合。但请考虑以下伪代码:
@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 被池化以避免在更改状态时出现线程问题(?!?)。就我个人而言,我更喜欢单例服务(类似 Spring),我从来没有得到 SLSB 的想法。是的,我知道 EJB 3.1 中的单例 EJB。
在使用 EJB 3.0 之后,我认为 Stateless Session bean 的存在是为了完善 Enterprise Bean 环境。他们确实在那里为您的其余业务逻辑设置外观。人们经常建议 SLSB 是线程安全的,但这至少可以说是误导。
当它们的代码路径包括调用非线程安全代码(例如,共享的非线程安全缓存)时,它们绝对不是线程安全的。 SLSLB 提供的唯一保证是最多一个线程同时使用单个 SLSB 实例。这基本上归结为 SLSB 具有同步的方法访问,并且将有多个实例来服务客户端调用。但是,让一个 SLSB 方法从这些多个实例的共享非线程安全类调用代码仍然可能造成严重破坏,并使有问题的 SLSB 成为非线程安全的。
由于 EE 上下文(事务、安全资源等)已经绑定到线程,所以我认为不需要 SLSB,而不是 Spring Singletons。它们确实补充了仅 EJB 应用程序中的 Statefull Session bean。
在我看来,他们选择使用 SLSB 的路线和 EJB 3.1 的新锁并发设置是为了让程序员变得笨拙,让 Mighty Container 满足您的需求。帮自己一个忙,阅读 Java Concurrency in Practice 并开始使用单例与股票 Java 线程并发结构相结合。(同步、易失、并发集合等)
与这里的大多数答案让您相信的相反,无状态与类本身的线程安全无关。这绝对不是@Stateless
. 开发人员本身仍然对表示@Stateless
EJB 的类没有声明任何实例变量(即没有状态)负责。容器不对那部分负责。基本上,开发人员必须说“嘿容器,这是一个无状态的业务服务类,我将用它进行注释,@Stateless
以便您可以将它用作无状态的 EJB”,而不是相反。
如果您想要状态,则使用@Stateful
每次客户端获取它时都会重新创建的 a例如,会话范围的 CDI 托管 bean,那么 EJB 将与该 bean 一样长,等等)。或者,使用@Singleton
基本上是应用程序范围并且实际上是线程锁定的。
无状态和池更多地与事务的线程安全有关。您可能已经知道@Stateless
默认情况下,对 a 的单个方法调用计为单个完整事务。然而,由于所有敏感的前处理和后处理工作,该事务又需要特定 EJB 实例上的线程锁。因此,EJB 基本上可以阻止所有其他想要调用相同方法的客户端,直到事务提交为止。这正是它们被克隆和按需汇集的原因。
请注意, a@Singleton
不是池化的,默认情况下实际上是线程锁定的。您现在应该明白,当 (ab) 用作“无状态 EJB”时@Singleton
,默认情况下 a 绝对不会比 a 快。@Stateless
另请参阅Java EE 7 教程“在单例会话 bean 中管理并发访问”。
第一个无状态会话 bean (SLSB) 是一种服务器端技术 - 例如,您不会在 Swing 代码中使用它们。
但是例如,它们被用作连接到中央服务器的许多客户端的“门面”。SLSB 包含业务逻辑,然后可以调用数据库。
由于 SLSB 可以池化,因此您不需要每个客户端一个 SLSB,而每个并发客户端只需要一个。当 SLSB 不使用时,它会被放回池中,然后可以用于下一个客户端。
由于 SLSB 被“托管”在容器中,它们是线程安全的,并且容器为您完成了很多繁重的工作:事务、安全性、资源注入等等。
从非 EJB 技术特定的角度来看,无状态会话 Bean 是基础架构代码,显然不保存任何状态,但传递具有状态的对象。在 EJB 之外的其他实现中,您的有状态会话 Bean 或域 POJO 可以看到状态。正如上面的评论所述,它是您的业务层的入口点或外观。
在 Java Web 应用程序中,您可以按层设计,例如控制器、服务类(SLSB 或只是一个普通的 Java 接口),然后是 DAO 或任何调用数据库/后端的东西。
然而,EJB 会自动提升一些样板,例如事务、安全性等。
无状态对象将使您能够将自身与客户端松散耦合,从而使您可以轻松扩展。
无状态会话 bean (SLB) 是用于抽象业务逻辑的服务器端 (EJB) 组件。由于这种无状态的本质,您可以轻松地将 SLB 部署在不同的容器中,该容器不在同一个 JVM 之上运行。根据您的要求,您可以拥有一个或多个容器来运行这些 bean。