我在应用程序中注册了 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)并调用它们。
如果上下文已经关闭,多播器似乎不应该处理对事件侦听器的调用。这种行为使我的应用程序做了一些在关机步骤不应该做的工作。
上下文关闭后如何防止对侦听器的调用?在应用程序上下文中实现的事件发布者不检查当前上下文是否关闭。