我在应用程序中注册了 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 关闭上下文、销毁所有 bean 并将上下文的 closed 属性设置为 true 后接收到 HttpSessionDestroyedEvent 事件。但上下文仍然存在,它的发布方法获取 applicationEventMulticaster 并告诉他多播此事件。然后 multicaster 获取它的注册监听器列表,执行 getBean(此时 BeanFactory 创建这个 beans)并调用它们。
在上下文已经关闭的情况下,多播器似乎不应该处理对事件监听器的调用。此行为使我的应用程序执行了一些不应在关闭步骤完成的工作。
如何在上下文关闭后阻止对监听器的调用?在应用程序上下文中实现的事件发布者不会检查当前上下文是否未关闭。
最佳答案
在这个特定示例中,您能否在发布事件之前检查一下上下文是否已关闭?
public void sessionDestroyed(HttpSessionEvent event) {
ApplicationContext context = getContext(event.getSession().getServletContext());
if(((ConfigurableApplicationContext)context).isActive()) {
HttpSessionDestroyedEvent e = new HttpSessionDestroyedEvent(event.getSession());
context.publishEvent(e);
}
}
关于spring - 为什么 Spring 允许在封闭的应用程序上下文中发布事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12386926/