为什么Spring允许在封闭的应用程序上下文中发布事件

时间:2012-09-12 11:17:38

标签: spring grails

我在应用程序中注册了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并将context的closed属性设置为true。但是上下文仍然存在,它的发布方法获得applicationEventMulticaster并告诉他多播这个事件。然后,multicaster获取已注册的侦听器列表,执行getBean(此时BeanFactory创建此bean)并调用它们。

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

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

1 个答案:

答案 0 :(得分: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);
    }
}