这是一个运行在WAS8.0上的JSF2应用程序。下面是一个页面的“支持”bean的代码。
@Named("mySessionBean")
@SessionScoped
@Stateful
@LocalBean
@StatefulTimeout(unit = TimeUnit.MINUTES, value = 10)
public class MySessionBean implements Serializable {
@PostConstruct
public void init()
{
System.out.println("start MySessionBean: " + this.hashCode());
}
@PreDestroy
public void cleanup()
{
System.out.println("destroy MySessionBean: " + this.hashCode());
}
....
}在web.xml中设置的会话超时值小于bean的超时值。当我运行应用程序时,我看到了来自@PostConstruct的打印输出,但从未看到来自@PreDestroy的打印输出。我尝试了以下两种场景: 1.注销- invalidateSession;2.简单地等待,直到会话到期。
我不是这个应用的设计者。设计人员坚持将所有支持bean作为有状态会话bean。我认为更主流的方法是让它们成为CDI bean。但不管怎样,当我将注释更改为仅CDI时,我也开始从@PreDestroy获得打印输出
@Named("mySessionBean")
@SessionScoped
public class MySessionBean implements Serializable {
.....我的问题是,在第一种情况下,我没有得到@PreDestroy方法调用的原因是什么?如果我看不到@PreDestroy被调用,有没有其他方法可以跟踪“支持”bean(在本例中是有状态会话bean)的生命周期。谢谢!
发布于 2013-02-07 15:26:24
看看Java EE 6 Tutorial的这一部分,它显示了有状态会话bean的生命周期。只有在从客户端代码中显式删除bean时,才会调用PreDestroy方法,调用带有@Remove注释的方法。
发布于 2013-04-22 23:14:23
另一个答案链接到一个Java EE 6 Tutorial,它甚至没有提到超时的存在。我也不认为教程明确指出@PreDestroy方法只在显式的@Remove方法调用之后调用。因果关系没有说明,它只描述了两个事件,不一定是直接相关的:
在生命周期结束时,客户端调用注释为@Remove的方法,而EJB容器调用注释为@PreDestroy的方法(如果有的话)。
WebSphere docs提到了以下内容:
当调用remove方法时,将为有状态会话bean调用PreDestroy生命周期拦截器回调。还要记住,如果有状态会话bean在处于被动状态时超时,或者如果在对该bean的方法调用期间发生意外异常并且该bean被丢弃,则不会调用PreDestroy生命周期拦截器回调。
现在,它确实清楚地声明了,当调用方法时,PreDestroy回调将被调用。同时,它明确指出,如果PreDestroy在被动状态下超时,则不会调用SFSB回调。因此,这意味着当SFSB未处于被动状态时,它们确实会被调用?
现在让我们来看看JBoss。
首先,如果removalTimeout < idleTimeout,则在移除超时时不会调用PreDestroy的JBoss issue。似乎在5.2中得到了修复。
其次,我刚刚在SFSB4.3上测试了一下,当一个钝化的JBoss在超时被移除时会发生什么--它在销毁之前被激活了。
因此,对于超时和bean删除应该如何表现,似乎存在多种解释。
https://stackoverflow.com/questions/14740302
复制相似问题