我了解到CDI Bean可用于不同的基于Web应用程序的范围(仅在那里,对吧?)。例如:@ RequestScoped,@ SessionScoped等。 @SessionScoped通过完整的浏览器会话将数据保存在托管bean中。这在逻辑上听起来很安静,因为注释名称描述了它的作用。 但是 - 现在我仔细研究了EJB会话bean。到目前为止我知道,这样的情况可能有三种状态之一:@ Stateless,@ Stateful和@Singleton。 对我来说,看起来这些与CDI bean的注释之间存在直接的可比性:@RequestScoped - > @Stateless,@ SessionScoped - > @Stateful,@ ApplicationScoped - > @辛格尔顿。 但是由于我正在研究一些例子,我发现了一个包含@Stateful和@SessionScoped注释的bean。 我找了一个解释 - 但我找不到任何可以理解的答案。那么,究竟有什么区别呢?为什么我必须同时使用这两个注释?谢谢。
答案 0 :(得分:1)
CDI Beans可用于不同的基于Web应用程序的范围(仅在那里,对吧?)。
错误。 CDI bean可以在您想要的任何地方使用 - 数据库连接/通信,业务逻辑,基于事件的编程,即使在Java SE中(Weld,CDI的参考实现,甚至提供此功能)。
但是,特别是@SessionScoped
bean在HTTP会话中比其他任何地方都更有意义。但是你仍然可以想象(和使用)会话作为给定的时间段,标记开头和结尾。在这些边界内,会话存在 - 不需要是HTTP会话,但它是最明显的会话。
这些与CDI bean的注释之间的直接可比性:@RequestScoped - > @Stateless,@ SessionScoped - > @Stateful,@ ApplicationScoped - > @Singleton。
再次错了。 EJB只与Web通信相关联,而CDI则不然。同样基于您选择的注释,您还可以选择一个容器(CDI / EJB)来负责该bean。 CDI集成了所有EJB bean(创建代理并使其“看似”为CDI bean - 允许您在EJB bean中使用CDI)。
现在,例如,@Stateless
在CDi / Weld内部表示为@Dependent
范围,而不是@RequestScoped
,因为EJB中的@Stateless
bean 重新使用,你不能真正了解他们的状态。在CDI中使用@RequestScoped
时,您可以激活请求上下文(让我们坚持使用HTTP,通过发送您激活它的内容),这会触发所有@RequestScoped
bean的创建。在请求之后,所有这些bean都被销毁,从未再次使用过。所以你可以完全依赖你放在里面的东西,你也可以确保它不会在请求之后生效。
另一个故事是@ApplicationScoped
与@Singleton
。这些确实非常相似,最重要的细节可能是CDI创建自己的bean代理。但这对于这个问题来说太详细了,我想你现在可以认为它们具有可比性。
@SessionScoped(CDI)和@Stateful(Java EE)之间的差异
现在终于到了原来的问题。我认为要掌握这些差异,你需要了解CDI在上下文上运行的事实。它总是激活上下文(在这种情况下是会话上下文),并且在那一刻,一组@SessionScoped
bean出现,你可以与它们通信,它们有值和状态等。上下文中断,所以在同一时间a请求上下文可能存在,应用程序上下文确实存在。因此我们可以说@SessionScoped
与会话绑定并由容器控制,而@Stateful
为您提供用户管理的会话,其生命周期由客户端管理,并且还添加了许多其他功能除此之外。
您有时可以在一个bean上看到两个注释的原因是人们将它们组合在一起以获得两全其美 - 容器管理生命周期和添加的功能。但请注意,尽管@Stateful
目前使用频率较高(选择加入@Stateless
通常更有意义),@SessionScope
更具普遍性,几乎适用于任何会话 - 基于情景。
希望它至少有一些亮点,恐怕这是一个非常复杂的话题。
答案 1 :(得分:0)
EJB Bean默认为您提供Transaction, CDI豆没有。
我认为这是差异