我想知道,之间的主要区别是什么:
- javax.enterprise.context.SessionScoped和 javax.ejb.Stateful
- javax.enterprise.context.ApplicationScoped 和 javax.ejb.Singleton
我知道 @SessionScoped 和 @Stateful 允许为每个客户端创建一个新实例。我还知道对于 @ApplicationScoped 和 @Singleton/@Stateless 它们在客户端之间共享。
=> 但我什么时候应该考虑是选择 EJB 还是其他更好?
@SessionScoped
表示范围,而 @Stateful
在某种程度上我们现在称之为构造型。 @Stateful
为一个bean添加了一些服务,其中包括事务行为和钝化。
然而,@Stateful
的核心是它的 session 行为,这确实与 session 范围重叠。
不同之处在于 session 范围绑定(bind)到 HTTP session ,而 @Stateful
是一个开放式的用户管理 session ,其生命周期由引用 bean 的客户端管理代理。
@Stateful
远程 bean 最初是 Servlet 的二进制 (RMI) 计数器部分。 Servlet 监听来自浏览器的远程 HTTP 请求,@Stateful
远程 bean 监听来自 Applets(以及后来的 Swing 客户端)的远程 RMI 请求。
不幸的是,两者之间存在许多不一致之处。 Servlet 只是一个 HTTP 监听器,而 @Stateful
beans 自动引入了许多其他功能。 Servlet 还与所有其他 Servlet 共享 session ,并在 war 中与所有其他 Servlet 共享 Java EE 组件命名空间,而对于 @Stateful
EJB,每个单独的 bean 都有自己的 session 和组件命名空间。
随着 EJB 2 中本地 bean 的引入以及用于远程 EJB 通信的 Swing/Applet 客户端的急剧减少,为 @Stateful
bean 维护的 session 的功能变得不太清楚。
我认为可以公平地说 @Stateful
这些天使用得不多了。对于 Web 应用程序,HTTP session 几乎总是领先的,这意味着将 session 范围和本地 @Stateless
bean 和/或 CDI bean 用于业务逻辑。
在某些情况下,需要使用 @Stateful
bean 来自然支持来自 JPA 的扩展持久性上下文及其钝化功能(Servlet 没有标准化的钝化机制)。请注意,@Stateful
和 @SessionScoped
(或许多其他范围)可以结合使用。将它们结合起来的好处是用户代码不再需要管理生命周期,而是由容器来管理。
@ApplicationScoped
和@Singleton
有一些相似的故事,尽管没有遗留问题(@Singleton
是一个相当新的东西)。 @ApplicationScoped
只是一个作用域,而 @Singleton
是一个 bean 类型(如果您愿意,可以是构造型),它不仅为您提供应用程序作用域的行为,还为您提供再次具有事务行为,具有自动锁定(可以通过 @Lock
进行调整)和急切构造行为(通过 @Startup
)。
尽管 @Stateful
和 @Singleton
本身非常方便,但 Java EE 目前的发展方向似乎是将这些内置构造型分解为单独可用的注释谁知道呢,也许有一天它们会成为由那些分解的注释组成的实际 CDI 原型(prototype)。