@SessionScoped 表示作用域,而@Stateful 在某种程度上是我们现在所说的构造型。 @Stateful 给 bean 添加一个服务,其中包括事务行为和钝化。
@Stateful 的核心是它的会话行为,它确实与会话范围重叠。
不同之处在于会话范围与 HTTP 会话相关联,而@Stateful 是一个开放式用户管理会话,其生命周期由引用 bean 代理的客户端管理。
@Stateful 远程 bean 最初是 Servlet 的二进制 (RMI) 计数器部分。 Servlet 监听来自浏览器的远程 HTTP 请求,@Stateful 远程 bean 监听来自 Applet(以及后来的 Swing 客户端)的远程 RMI 请求。
不幸的是,两者之间存在许多不一致之处。 Servlet 只是一个 HTTP 侦听器,而 @Stateful bean 自动引入了许多其他特性。 Servlet 还与所有其他 Servlet 共享会话,并且还与所有其他 Servlet 共享 Java EE 组件名称空间,而对于 @Stateful EJB,每个单独的 bean 都有自己的会话和组件名称空间。
随着 EJB 2 中本地 bean 的引入以及用于远程 EJB 通信的 Swing/Applet 客户端的急剧下降,为 @Stateful bean 维护的会话功能变得不那么清晰了。
我认为可以公平地说@Stateful 这些天根本就没有那么多人使用。对于 Web 应用程序,HTTP 会话几乎总是处于领先地位,这意味着将会话范围和本地 @Stateless bean 和/或 CDI bean 用于业务逻辑。
在某些情况下,@Stateful bean 需要它们自然地支持来自 JPA 的扩展持久性上下文以及它们的钝化特性(Servlet 没有标准化的钝化机制)。请注意,@Stateful 和 @SessionScoped(或许多其他范围)可以组合使用。结合它们的好处是用户代码不再需要管理生命周期,而是由容器来管理。
@ApplicationScoped 和 @Singleton 的故事有些相似,尽管没有遗留(@Singleton 是一个相当新的事物)。 @ApplicationScoped 只是一个作用域,而@Singleton 是一个 bean 类型(如果您愿意,可以使用原型),它不仅为您提供应用程序作用域的行为,而且还为您再次提供事务行为,自动锁定(可以是通过 @Lock 调整并具有急切的构造行为(通过 @Startup)。
虽然@Stateful 和@Singleton 本身非常方便,但Java EE 的当前前进方式似乎是将这些内置原型分解为单独可用的注释,谁知道,也许有一天它们会成为真正的CDI由这些分解的注释组成的原型。