jakarta-ee - @SessionScoped (CDI) 和 @Stateful (Java EE) 之间的区别

标签 jakarta-ee annotations cdi stateful session-scope

我了解到 CDI Bean 可以用于不同的基于 Web 应用程序的范围(仅限于此,对吧?)。例如:@RequestScoped、@SessionScoped等。 @SessionScoped 将数据保存在整个浏览器 session 上的托管 bean 中。这在逻辑上听起来很安静,因为注释名称描述了它的作用。 然而,现在我更仔细地了解了 EJB session Bean。到目前为止我知道,这样的状态可能具有以下三种状态之一:@Stateless、@Stateful 和@Singleton。 对我来说,看起来它们和 CDI bean 的注释之间有直接的可比性:@RequestScoped --> @Stateless、@SessionScoped --> @Stateful、@ApplicationScoped --> @Singleton。 但由于我正在研究一些示例,我发现了一个同时包含 @Stateful 和 @SessionScoped 注释的 bean。 我寻找解释 - 但我没有找到任何可以理解的答案。那么,到底有什么区别呢?为什么我必须使用这两个注释?谢谢。

最佳答案

CDI Beans can be used in different web-application-based scopes (only there, right?).

错了。 CDI bean 可以用在您想要的任何地方 - 数据库连接/通信、业务逻辑、基于事件的编程,甚至在 Java SE 中也是如此(Weld,CDI 的引用实现,现在也提供了这一点)。 然而,特别是 @SessionScoped bean 在 HTTP session 中比其他任何地方都更有意义。但您仍然可以将 session 想象(并使用)为具有标记开始和结束的给定时间段。在这些边界内, session 是存在的 - 不一定是 HTTP session ,但它是最明显的 session 。

direct comparability between those and the annotations of a CDI bean: @RequestScoped --> @Stateless, @SessionScoped --> @Stateful , @ApplicationScoped --> @Singleton.

又错了。 EJB 仅链接到 Web 通信,而 CDI 则不然。另外,根据您选择的注释,您还可以选择一个负责该 bean 的容器 (CDI/EJB)。 CDI 集成了所有 EJB bean(创建代理并使其“看似”是一个 CDI bean - 允许您在 EJB bean 中使用 CDI 内容)。

例如,@Stateless 在 CDi/Weld 中内部表示为 @Dependent 范围,而不是 @RequestScoped,因为 重用的,您无法真正了解它们的状态。在 CDI 中使用 @RequestScoped 时,您可以激活请求上下文(让我们坚持使用 HTTP,因此通过发送一些内容来激活它),这会触发所有 @RequestScoped 的创建 bean 类。请求之后,所有这些 bean 都被销毁,不再使用。因此,您可以完全依赖您放入其中的内容,并且还可以确保它在请求后不会继续存在。

另一个故事是@ApplicationScoped@Singleton。它们确实非常相似,最重要的细节可能是 CDI 创建自己的 Bean 代理。但这对于这个问题来说太详细了,我想你现在可以认为它们具有可比性。

Diff between @SessionScoped (CDI) and @Stateful (Java EE)

现在终于回到原来的问题了。我认为要总体把握这些差异,您需要了解 CDI 在上下文上运行的事实。它总是激活上下文(在本例中为 session 上下文),此时一组 @SessionScoped bean 出现,您可以与它们进行通信,它们具有值和状态等。上下文相互交叉,因此同时,请求上下文可能存在,并且应用程序上下文确实存在。因此,我们可以说 @SessionScoped 与 session 绑定(bind)并由容器控制,而 @Stateful 为您提供用户管理的 session ,其生命周期由客户端管理,除此之外,它还添加了许多其他功能。

有时您可以在一个 bean 上看到两个注释的原因是人们将它们组合起来以获得两全其美的效果 - 容器管理的生命周期和添加的功能。但请注意,虽然 @Stateful 目前使用不多(选择 @Stateless 通常更有意义),但 @SessionScope > 更加通用,几乎适合任何基于 session 的场景。

希望它至少能带来一些启发,恐怕这是一个非常复杂的话题。

关于jakarta-ee - @SessionScoped (CDI) 和 @Stateful (Java EE) 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40024844/

相关文章:

java - 在 Web 应用程序中出现奇怪的错误

spring - 如何在 Spring 4 中开启注解驱动验证?

java - 如何强制 Java 子类定义注解?

java - 在 Java SE 中使用 CDI 和 JPA 最简单的方法是什么?

java - 如何强制 CDI/Weld 使用 new 关键字?

javax.enterprise.inject.Vetoed 打开 web beans,哪个 jar?

java - 如何在java中编码以使用cygwin在Windows环境中运行内部使用rSync的unix shell脚本?

java - 如何在 Servlet 上创建 REST API 以使用访问 token 进行身份验证

java - 客户端中的@EJB 注释

java - Spring Security 使用模型属性来应用角色