为什么选择无状态会话 Bean?
我正在阅读有关无状态会话 bean 的内容,但无法理解它的用途。
摘自下面的 sun 教程
“..因为无状态会话 bean 可以支持多个客户端,因此它们可以为需要大量客户端的应用程序提供更好的可伸缩性”
无状态会话 bean 在哪里使用?什么样的应用程序使用它?
在“无状态会话 bean”出现之前使用什么机制来支持类似上下文中的多个客户端?
有人可以提供一些详细信息吗?
谢谢你!
I was reading about stateless session bean and couldn't understand it's use.
Excerpt from sun tutorial below
"..Because stateless session beans can support multiple clients, they can offer better scalability for applications that require large numbers of clients"
Where stateless session bean is being used? what kind of applications use it?
What mechanism has been being used before the advent of 'stateless session bean' to support multiple clients in the similar contexts?
Can anyone please provide some details?
thank you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
老实说,很难找到 SLSB 的任何合理用例。由于它们不保持任何状态(正如名称所示),因此它们本质上应该是线程安全的。即使它们是由容器汇集的。
另一方面,人们很容易将它们用作安全的临时存储,因为它们保证是线程安全的(由于池化),您不需要任何同步或线程安全的集合。 但是请考虑以下伪代码:
客户端:
此代码(尽管很粗俗)非常好,并且不需要
AtomicInteger
等。您期望什么结果?实际上,任何非负值都是可能的...对
slsb
的任何调用都可能由Slsb
的不同实例提供,同时您的(以前使用的)实例可能有被用来服务不同的客户。结论:在 SLSB 中存储状态是错误的,但由于某种原因,SLSB 被池化以避免更改状态时出现线程问题(?!?)。 个人我更喜欢单例服务(类似 Spring),我从来没有得到 SLSB 的想法。是的,我知道 EJB 3.1 中存在单例 EJB。To be honest, it is hard to find any reasonable use case for SLSBs. Since they don't hold any state (as the name imposes), they should be inherently thread-safe. Even though they are pooled by the container.
On the other hand it is tempting to use them as a safe temporary storage as they are guaranteed to be thread-safe (thanks to pooling), you don't need any synchronization or thread-safe collections. But consider the following pseude-code:
Client-side:
This code (despite its vulgarity) is perfectly fine and it does not require
AtomicInteger
for instance.What result do you expect? Actually, any non-negative value is possible... Any call to
slsb
might be served by different instance ofSlsb
and in the meantime your (previously used) instance might have been used to serve different clients. Conclusion: storing state in SLSB is wrong, but for some reason SLSBs are pooled to avoid threading issues when changing the state (?!?). Personally I much prefer singleton services (Spring-like) and I have never got the SLSB idea. And yes, I am aware of singleton EJBs in EJB 3.1.使用过 EJB 3.0 后,我认为无状态会话 Bean 可以完善 Enterprise Bean 环境。它们确实是为您的其余业务逻辑设置一个外观。人们经常建议 SLSB 是线程安全的,但这至少可以说是一种误导。
当它们的代码路径包含调用非线程安全代码(例如共享的非线程安全缓存)时,它们绝对不是线程安全的。SLSB 提供的唯一保证是单个 SLSB 实例最多同时被一个线程使用。这基本上可以归结为 SLSB 具有同步方法访问,并且将有多个实例来服务客户端调用。但是,使用 SLSB 方法从这些多个实例中的共享非线程安全类调用代码仍然可能造成严重破坏,并且会使相关 SLSB 变得非线程安全。
由于 EE 上下文(事务、安全资源等)已经绑定到线程,我认为不需要 SLSB 而不是 Spring 单例。它们确实补充了纯 EJB 应用程序中的 Statefull Session beans。
在我看来,他们选择的 SLSB 路线和 EJB 3.1 的新锁并发设置是试图让程序员变得愚蠢,并让 Mighty Container 满足您的需求。帮自己一个忙,阅读《Java 并发实践》,并开始使用单例与常用的 Java 线程并发结构。 (同步、易失、并发集合等)
Having used EJB 3.0, in my opinion Stateless Session beans are there as to complete the Enterprise Bean landscape. They indeed are there to setup a Facade to the rest of your business logic. People often suggest SLSB's to be threadsafe, but this is misleading to say the least.
They are definitely not thread safe when their codepath includes calling non-threadsafe code (eg. a shared non threadsafe cache).The only guarantee that SLSLB give is that a single SLSB instance is used by at most one thread at the same time. This basically boils down to SLSB's having synchronized method access, and that there will be multiple instances to serve client calls. But having a SLSB method calling code from a shared non-thread safe class from these multiple instance could still wreak havoc and would render the SLSB in question non-threadsafe.
Since EE contexts (transactions , security resources etc) are bound to the thread already I see no need for SLSB over say Spring Singletons. They do complement Statefull Session beans in an EJB-only application.
In my opinion the route they choose with SLSB's and the new lock concurrency settings for EJB 3.1 is an attempt to dumb down the programmer and have the Mighty Container serve your needs. Do yourself a favor and go read Java Concurrency in Practice and start using singletons combined with stock java thread concurrency constructs. (synchronized, volatile, concurrent collections etc.)
与这里大多数答案让您相信的相反,无状态性与类本身的线程安全性无关。这绝对不是@Stateless 的主要目标。开发人员本身仍然要对表示
@Stateless
EJB 的类没有声明任何实例变量(即没有状态)负责。容器不负责该部分。基本上,开发人员必须说“嘿容器,这是一个无状态业务服务类,我将用@Stateless
注释它,以便您可以将它用作无状态 EJB”,而不是相反左右。如果你想要状态,那么使用@Stateful,每次客户端获取它时都会重新创建它(因此,如果客户端是一个视图范围的JSF托管bean,那么EJB将存活很长时间作为该 bean,或者如果客户端是会话范围的 CDI 托管 bean,则 EJB 将与该 bean 一样长地存在,等等)。或者,使用@Singleton,它基本上是应用程序范围的并且实际上是线程锁定的。
无状态和池化与事务的线程安全性有更多关系。您可能已经知道,默认情况下,@Stateless 上的单个方法调用算作单个完整事务。然而,由于所有敏感的预处理和后处理工作,该事务又需要特定 EJB 实例上的线程锁。因此,EJB 基本上可以阻止所有其他想要调用相同方法的客户端,直到事务提交为止。 这正是它们按需克隆和汇集的原因。
请注意,
@Singleton
不是池化的,并且默认情况下实际上是线程锁定的。现在您应该明白,当(ab)用作“无状态 EJB”时,@Singleton
默认情况下绝对不比@Stateless
快。另请参阅 Java EE 7 教程“管理单例中的并发访问”会话 bean”。另请参阅:
In contrary to what most answers here let you believe, statelessness has nothing to do with threadsafety of the class itself. That's absolutely not the primary goal of
@Stateless
. The developer itself is still responsible for that the class representing a@Stateless
EJB doesn't have any instance variables declared (i.e. no state). The container isn't responsible for that part. Basically, the developer must say "Hey container, here's a stateless business service class, I'll annotate it with@Stateless
so that you can use it as a stateless EJB" and thus not the other way round or so.If you want state, then use a
@Stateful
which will be newly recreated every time the client obtains it (so, if the client is e.g. a view scoped JSF managed bean, then the EJB will live as long as that bean, or if the client is e.g. a session scoped CDI managed bean, then the EJB will live as long as that bean, etc). Or, use a@Singleton
which is basically application scoped and actually thread locked.Statelessness and pooling has more to do with threadsafety of transactions. You probably already know that a single method call on a
@Stateless
counts by default as a single full transaction. However, that transaction in turn requires a thread lock on the specific EJB instance, because of all the sensitive pre- and post processing work. So the EJB could basically block all other clients wanting to call the same method until the transaction is committed. That is exactly why they are cloned and pooled on demand.Do note that a
@Singleton
is not pooled and is by default actually thread locked. You should by now understand that a@Singleton
is by default absolutely not faster than a@Stateless
when (ab)used as a "stateless EJB". See also a.o. Java EE 7 tutorial "Managing concurrent access in a singleton session bean".See also:
第一个无状态会话 bean (SLSB) 是一种服务器端技术 - 例如,您不会在 swing 代码中使用它们。
但它们被用作许多连接到中央服务器的客户端的“外观”。 SLSB 包含业务逻辑,然后可以调用数据库等。
由于 SLSB 可以池化,因此您不需要为每个客户端配备一个 SLSB,而只需为每个并发客户端配备一个 SLSB。当 SLSB 不使用时,它会被放回池中,然后可供下一个客户端使用。
由于 SLSB“托管”在容器中,因此它们是线程安全的,并且容器会为您完成许多繁重的工作:事务、安全性、资源注入等。
First Stateless session beans (SLSB) are a server side technology - you don't use them within swing code for example.
But they are for example used as a "Facade" for many clients that connect to central servers. SLSB contain business logic and can then e.g. call into databases.
As SLSB can be pooled, you do not need one SLSB per client, but only one per simultaneous client. When the SLSB is not used, it is put back into the pool and can then be used for the next client.
As the SLSBs are 'hosted' in a container, they are thread safe and the container does a lot of the heaving lifting for you: transactions, security, resource injection and so on.
从非 EJB 技术特定的角度来看,无状态会话 Bean 是基础设施代码,显然不保存任何状态,但传递具有状态的对象。状态可以通过 EJB 之外的其他实现中的有状态会话 Bean 或域 POJO 来查看。正如上面的评论所述,它是业务层的入口点或外观。
在 Java Web 应用程序中,您可以按层进行设计,例如控制器、服务类(SLSB 或只是一个普通的 Java 接口),然后是 DAO 或任何调用数据库/后端的内容。
然而,EJB 会自动提升一些样板代码,例如事务、安全性等。
From a non-EJB technology specific standpoint, Stateless Session Beans are infrastructure code that obviously does not hold any state but passes objects that have state. State can beheld by your Stateful Session Beans or Domain POJOs in other implementations outside an EJB. As the comment above states, it is an entry point or facade to your business layer.
In a java web application, you can design by layer such as Controller, Service class (SLSB or just a plain Java interace) then DAO or whatever to call a database/backend.
EJB however does some automatic lifting of boiler plate such as transactions, security and such.
无状态对象将使您能够将自身与客户端松散耦合,从而使您可以轻松横向扩展。
无状态会话 Bean (SLB) 是服务器端 (EJB) 组件,用于抽象业务逻辑。由于无状态的这种本质,您可以轻松地将 SLB 部署在不在同一 JVM 之上运行的不同容器中。根据您的要求,您可以让一个或多个容器运行这些 Bean。
Stateless object will enable you to loosely couple itself from the client and thus allows you to scale out easily.
Stateless session beans (SLB) are server side (EJB) components which are used to abstract your business logic. Because of this very nature of stateless ness you can easily deploy your SLBs in a different container which is not running on top of the same JVM. And as per your requirement you can have one or more containers running these beans.