在会话超时时删除JSF托管bean



我在弄清楚如何正确处理JSF中会话的自动销毁时遇到了麻烦。当然,此时,会话被容器失效,导致@PreDestroy方法也在会话作用域的bean上被调用。

在一些会话作用域bean的PreDestroy中,我们取消了一些侦听器的注册,如下所示:

@PreDestroy
public void destroy() {
    getWS().removeLanguageChangeListener(this);
}

然而,getWS()方法实际上试图获取对另一个会话作用域bean的引用,但是失败了,因为FacesContext.getCurrentInstance()返回null。根据Ryan Lubke的说法,后者似乎是正常的JSF行为:

我们在这里严格遵守规范。我不确定这样假设是否安全FacesContext将在所有的@PreDestroy情况下可用。考虑会话作用域的bean。该会话可能会超时由于不活动导致的容器。facecontext不能在。

对我来说很好,但是如何确保所有对象都被正确清除呢?它是坏的做法,以消除自我作为听众在PreDestroy?或者我们只需要为请求/视图作用域的bean做这个,因为它们比WS(来自getWS())的会话作用域的时间要短?

请注意,我在Tomcat7上得到了这个行为,但我希望这个问题在每个容器上都发生。

我认为会话bean是在servlet容器上的专用线程中清理的,因此在FacesContext(与JSF Request相关联)之外。您可以使用HttpSessionListener来克服这个问题并清理会话资源。比如:

@WebListener
public class LifetimeHttpSessionListener implements HttpSessionListener {
@Override
public void sessionCreated(final HttpSessionEvent e) {
    // create some instance here and save it in HttpSession map
    HttpSession session = e.getSession();
    session.setAttribute("some_key", someInstance);
    // or elsewhere in JSF context:
    // FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("some_key", someInstance);
}
@Override
public void sessionDestroyed(final HttpSessionEvent e) {
    // get resources and cleanup them here
    HttpSession session = e.getSession();
    Object someInstance = session.getAttribute("some_key");
}
}

希望对大家有所帮助

相关内容

  • 没有找到相关文章

最新更新