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

标签 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 关闭上下文、销毁所有 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/

相关文章:

java - 来自 javax.validation.constraints 的注释与自定义 ConstraintValidator 相结合

java - 替换 Servlet Filter 中的响应内容

java - 使用多个数据源的 Spring 事务管理

grails - 面对空指针异常:无法在空对象上调用方法firstMethod():Grails 3.2.10

grails - 为什么Grails域验证会拒绝类似http://wctest.jenkins:8080/CRMGateway的网址

ajax - Grails 使用 JSON 响应。

mysql - UTF-8 仅在 Grails 1.1 数据库表中

java - HQL IF 子句不适用于 IS NOT NULL

java - Spring Boot @RestController,在 @RequestBody 中反序列化 Collection 时容忍 MismatchedInputException

grails - 为所有 GORM 对象添加属性和方法