@ApplicationScoped必须是可序列化的吗?

时间:2017-05-30 15:10:17

标签: java java-ee serialization cdi

我现在正在Java EE 7 tutorial了解CDI范围,并在最后一段中找到它说

  

使用会话,应用程序或会话范围的Bean必须是可序列化的,但使用请求范围的bean不必是可序列化的。

但令我困惑的是,在我的IDE(Netbeans和IntelliJ Idea)中,当我使用@SessionScoped或@ConversationScoped时,如果我没有像Java EE 7那样实现Serializable,它会给我一个错误教程说,显然,我无法构建项目然后运行它。当我使用@ApplicationScoped但没有实现Serializable时,事情变得奇怪,没有错误出现,我可以构建然后正常运行应用程序。

所以我对此非常好奇并且真的想知道原因。你能解释一下那里发生了什么吗?非常感谢你!

2 个答案:

答案 0 :(得分:1)

IDE中的错误基本上是因为你的IDE有一些插件(不可信任100%btw)。

序列化的原因如下:

  • @SessionScoped bean

    • 这些不仅仅是CDI规范处理,其他规格对它们有要求
    • 即,容器可以选择存储钝化会话以保存资源
    • 另一个故事是服务器之间的复制,因此您的请求可以在多个节点上处理(故障转移方案等)。
    • 我们不知道为什么,但正因为如此,我们必须确保这些bean 始终可序列化
  • @ConversationScoped bean

    • 几乎相同的故事,不是其他规格会对它们有要求,但这些bean在会话范围内“活”并且可以在会话期间存活(如果没有尽快结束)
    • 由于这些原因,当服务器钝化/复制会话以及会话范围的bean时,它当然也必须钝化/复制会话范围的bean
  • @ApplicationScoped bean

    • 这些可序列化,但在某些情况下,即使不是
    • ,您的应用也会正常工作
    • 这些情况是您可以避免序列化,例如在单节点应用程序服务器上运行
    • 只要您需要将此类bean复制到多个节点中,您就需要将其序列化为
    • 可以省略可串行化的另一种情况是SE
    • 因此,您的IDE非常智能,并且不会强制Serializable存在

答案 1 :(得分:1)

Serializable标记是bean的必需属性之一,它具有钝化能力(能够从活动状态转换为某种第二非活动状态)。如果bean具有钝化作用域(具有属性passivating=true的作用域),则bean必须具有钝化功能。根据CDI规范1.1。只有SessionConversation范围是钝化范围。

  

第6.6.4章钝化范围   例如,内置的会话会话范围定义在   第6.7节是钝化范围。 没有其他内置范围   钝化范围。

因此,您的会话bean需要具有钝化能力 - 需要是Serializable,但您的应用程序范围bean不需要。此外,某些CDI容器在部署期间不会在会话作用域bean上丢失Serializable上的错误,而只是在它们实际需要将bean实例从活动状态转移到被动状态时(例如,实例限制已经过命中,内存使用等)

有关详细信息,请阅读CDI 1.1 spec 快乐的黑客