3

我正在 JBoss 上试验 EJB3,开发一个无状态 bean。基本上,一旦部署了模块,我就需要执行一些与加载应用程序设置相关的操作。为此,我将一个方法注释为@PostConstruct,据我所知,API 会指示容器在部署 bean 后并在投入使用之前调用它。(正确吗?)现在,我很困惑,因为从登录日志来看,该方法看起来不仅仅是在部署之后调用,而是在调用每个公开的方法之前调用。我只需要调用该方法一次,而不是每次收到调用。最好的方法是什么?

提前致谢

亚历山德罗·伊拉多

4

5 回答 5

2

无状态 bean 应该就是这样 - 无状态的。这意味着在使用中,您不应该知道或关心 bean 是从池中提取的还是根据您的请求构建的。我很难想象 PostConstruct 如何应用于无状态环境,因为我总是使用该函数来完成构建 bean 的状态。

显然,JBoss 要么放弃无状态 bean 的池化并每次都构建它们,要么,如果它使用池化,则将它们视为每次都重新构建(因为它们不应该携带状态信息)。实际上,我对它完全调用 PostConstruct 感到有些惊讶。

于 2009-07-10T10:51:50.407 回答
1

首先在 bean 上调用第一个方法之前调用 PostConstruct。如果不会调用任何方法,则不会调用任何 post 构造。

其次,您可以在 PreDestory 方法中执行反向操作以消除副作用。

无论如何,您必须执行哪种操作?

于 2009-07-10T21:17:34.963 回答
0

由应用服务器来管理 EJB 的生命周期。它可以决定在它认为合适的时候构造、初始化和拆除 bean。可能对无状态 bean 的每次调用都在 bean 类的一个新实例上,尽管这似乎是一件不合时宜的事情。

应用服务器是在同一个对象实例上多次调用@PostConstruct 方法,还是每次都在不同的实例上调用?尝试在构造函数和 @PostConstruct 方法中粘贴日志语句。

于 2009-07-10T11:01:00.370 回答
0

您的池中有多少个 SLSB?根据容器的不同,在@PostConstruct第一个客户端访问它之前可能不会被调用(不确定 JBoss),所以这可能就是为什么它看起来像每次访问都一样。在调用您的方法的次数等于您的池大小之后,看看它是否停止调用您的构建后方法会很有趣。

如果您在构建后方法中执行一些昂贵的操作,那么可以在启动时在 SFSB 中执行这些操作,并在构建后将 SFSB“注入”到您的 SLSB 中。

于 2009-07-10T11:01:34.567 回答
0

PostConstruct 在客户端运行 biz 方法之前被调用。这意味着如果 bean 没有被池化,容器将实例化 bean,进行注入,调用 @PostConstruct 方法,然后允许 biz 方法运行。

在池化的情况下,每次从池中拉出 bean 时都会运行 @PostConstruct 方法。对于无状态 bean,这将在每个方法调用之间。对于有状态 bean,这将在客户端查找或注入之后进行。

如果您需要在应用程序部署中运行某些东西,您的选项将取决于您拥有的 Java EE 版本。

对于 Java EE 6,您可以在包含 @PostConstruct 方法的 @Singleton EJB 上使用 @Startup。

对于 Java EE 5 及之前的版本,您必须在 Web 存档中使用 ServletContextListener。如果需要,可以让 ServletContextListener 调用 EJB。

然而,可能更重要的问题是您要将这些应用程序设置加载到哪里?如果您正在处理非集群的单个 JVM 配置,那么您可能希望将它们加载到某种类型的 Singleton 中。在 Java EE 5 中,您必须自己实现单例设计模式,或者在 EE 6 中使用 @Singleton EJB 类型。

于 2010-02-18T20:00:25.610 回答