2012-09-12 37 views
2

我在應用程序中註冊了HttpSessionListener(用Grails 1.3.6使用Spring 3.0.5編寫)。我捕獲sessionDestroyed事件,獲取Spring的應用程序上下文併發布事件。爲什麼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並告訴他組播此事件。然後,multicaster會獲取註冊監聽器的列表,並執行getBean(並且此時BeanFactory創建此Bean)並調用它們。

看來,在上下文已經關閉的情況下,多播器似乎不應該處理對事件監聽器的調用。這種行爲使我的應用程序做了一些不應該在關機步驟中完成的工作。

如何防止上下文關閉後對偵聽器的調用?在應用程序上下文中實現的事件發佈者不檢查當前上下文沒有關閉。

回答

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); 
    } 
} 
+0

是的,這是顯而易見的。但可能有另一種方式存在?這種行爲是否正確? –

相關問題