我正在JBoss上试验EJB3,开发无状态bean。基本上,一旦部署了模块,我需要执行一些与加载应用程序设置相关的操作。 为此,我将一个方法注释为@PostConstruct,据我所知,从API开始,指示容器在部署bean之后和服务之前调用它。 (正确?) 现在,我感到很困惑,因为从登录开始,该方法看起来并不是在部署之后调用,而是在调用每个公开的方法之前调用。 我只需要调用一次该方法,而不是每次都接到一个调用。什么是最好的方法?
提前致谢
Alessandro Ilardo
答案 0 :(得分:2)
无国籍豆应该就是那样 - 无国籍。这意味着在使用中,您既不能告诉或不关心bean是从池中提取还是根据您的请求构建的。我很难想象PostConstruct如何应用于无状态环境,因为我总是使用该函数来完成构建bean的状态。
显然,JBoss要么放弃无状态bean的池化,要么每次都将它们重新构建,或者,如果它正在使用池化,那么就像每次重建它们一样对待它们(因为它们不应该携带状态信息)。我实际上有点惊讶它根本不会调用PostConstruct。
答案 1 :(得分:1)
首先调用PostConstruct,然后在bean上调用第一个方法。如果不调用任何方法,则不会调用post构造。
其次,您可以在PreDestory方法中执行反向操作以消除副作用。
无论如何你必须采取哪种行动?
答案 2 :(得分:0)
由app服务器来管理EJB的生命周期。它可能决定在适合的时候构建,初始化和拆除豆类。可能是你对无状态bean的每次调用都在你的bean类的一个新实例上,尽管这看起来像是件事情。
app服务器是在同一对象实例上多次调用@PostConstruct方法,还是每次在不同的实例上调用?尝试在构造函数和@PostConstruct方法中粘贴日志语句。
答案 3 :(得分:0)
你的泳池里有多少SLSB?根据容器的不同,@PostConstruct
可能不会被调用,直到第一个客户端访问它(不确定JBoss),所以这可能就是为什么它看起来像是在每次访问时。看到它在调用你的方法之后停止调用你的post-construct方法的次数等于你的池大小会很有趣。
如果您在后构造方法中执行一些昂贵的操作,那么可以在启动时在SFSB中执行这些操作,并在后构造中将SFSB“注入”到您的SLSB中。
答案 4 :(得分:0)
在客户端运行biz方法之前调用PostConstruct。这意味着如果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类型。