差异:@SessionScoped vs @Stateful和@ApplicationScoped vs @Singleton

我想知道, 两者之间的主要区别是什么:

  1. javax.enterprise.context.SessionScoped和javax.ejb.Stateful
  2. javax.enterprise.context.ApplicationScoped和javax.ejb.Singleton

我知道@SessionScoped@Stateful允许为每个客户端创建一个新实例。 我也知道,对于@ApplicationScoped@Singleton / @Stateless,它们在客户端之间共享。

但是,我什么时候应该考虑选择一个EJB或另一个更好?

@SessionScoped表示范围,而@Stateful表示我们现在称之为@Stateful的方式。 @Stateful向bean添加一个服务号,其中包括事务行为和钝化。

然而,@ @Stateful是它的会话行为,它确实与会话范围重叠。

不同之处在于会话范围与HTTP会话相关联,而@Stateful是一个开放式的用户管理会话,其生命周期由具有bean代理引用的客户端管理。

@Stateful远程bean最初是二进制(RMI)计数器部分的Servlets。 Servlet监听来自浏览器的远程HTTP请求,@ @Stateful远程bean监听来自Applet(以及后来的Swing客户端)的远程RMI请求。

遗憾的是,两者之间存在许多不一致之处。 Servlet只是一个HTTP侦听器,而@Stateful bean自动引入了许多其他function。 Servlet还与所有其他Servlet共享会话,并且还与战争中的所有其他Servlet共享Java EE组件名称空间,而对于@Stateful EJB,每个单独的bean都有自己的会话和组件名称空间。

随着EJB 2中本地bean的引入以及用于远程EJB通信的Swing / Applet客户端的急剧下降,为@Stateful bean维护的会话function变得不那么清晰了。

我认为可以说@Stateful根本没用过多少。 对于Web应用程序,HTTP会话几乎总是领先,这意味着使用会话范围和本地@Stateless bean和/或CDI bean来实现业务逻辑。

在某些情况下,需要@Stateful bean来支持JPA的扩展持久化上下文及其钝化function(Servlet没有标准化的钝化机制)。 请注意,可以组合@Stateful@SessionScoped (或许多其他范围)。 组合它们的优点是用户代码不再需要管理生命周期,但容器管理它。

@ApplicationScoped@Singleton有一个类似的故事,虽然没有遗产( @Singleton是一个相当新的东西)。 @ApplicationScoped只是一个范围,而@Singleton是一个bean类型(如果你愿意的话是@Singleton型),它不仅给你应用程序范围的行为,而且还为你提供事务行为,自动锁定(可以通过@Lock )并且热切的施工行为(来自@Startup )。

尽管@Stateful@Singleton本身非常方便,但Java EE目前的方向似乎是将这些内置的构造型分解为可单独使用的注释,谁知道,也许有一天它们将成为由分解的那些组成的实际CDI构造型注释。