3

我在应用程序中注册了 HttpSessionListener(用 Grails 1.3.6 编写,使用 Spring 3.0.5)。我捕获 sessionDestroyed 事件,获取 Spring 的应用程序上下文并向其发布事件。

ApplicationContext getContext(ServletContext servletContext) {
    return WebApplicationContextUtils.getWebApplicationContext(servletContext);
}

public void sessionDestroyed(HttpSessionEvent event) {        
    HttpSessionDestroyedEvent e = new HttpSessionDestroyedEvent(event.getSession());
    ApplicationContext context = getContext(event.getSession().getServletContext());
    context.publishEvent(e);
}

这段代码在大多数情况下都能正常工作。但不是所有的。如果我的应用程序在 Tomcat 6 下的生产环境中运行并且应用程序服务器关闭,则 sessionDestroyed 方法会在 spring 关闭上下文后接收 HttpSessionDestroyedEvent 事件,销毁所有 bean 并将上下文的关闭属性设置为 true。但是上下文仍然存在,它的发布方法获取 applicationEventMulticaster 并告诉他多播此事件。然后多播器获取其已注册侦听器的列表,执行 getBean(此时 BeanFactory 创建此 bean)并调用它们。

如果上下文已经关闭,多播器似乎不应该处理对事件侦听器的调用。这种行为使我的应用程序做了一些在关机步​​骤不应该做的工作。

上下文关闭后如何防止对侦听器的调用?在应用程序上下文中实现的事件发布者不检查当前上下文是否关闭。

4

1 回答 1

1

在这个特定的示例中,您能否在发布事件之前检查自己是否关闭了上下文?

public void sessionDestroyed(HttpSessionEvent event) {        
    ApplicationContext context = getContext(event.getSession().getServletContext());
    if(((ConfigurableApplicationContext)context).isActive()) {
        HttpSessionDestroyedEvent e = new HttpSessionDestroyedEvent(event.getSession());
        context.publishEvent(e);
    }
}
于 2012-09-12T12:30:38.533 回答