2011-03-01 174 views
6

使用Spring 3.0.5 GA@PreDestroy不叫会话作用域的Spring Bean在Tomcat关闭

有一个session作用域的bean与@PreDestroy方法。只是注意到,如果拥有HttpSession超时(即超过Servlet容器的会话超时值),则发出@PreDestroy回调。但是,如果我只关闭应用程序服务器,则不会调用@PreDestroy。是由设计还是错误?如果是后者,有什么建议可以解决?

FWIW,在单例bean上的@PreDestroy在两种情况下都被调用。

感谢, -nikita

PS。有一个可能相关的Spring bug - SPR-7359

回答

6

有趣。会话范围的bean在发生会话关闭事件时调用它们的@Predestroy。如果容器从不发送该事件,那么Spring将不会被通知。我不确定这是否构成错误,如果是这样,它是Spring或Tomcat中的错误。后者似乎更有可能,但我不知道Servlet容器是否有义务这样做。

如果这对你来说是一个阻碍,你可能想考虑让scoped bean在@PostConstruct期间注册一个“registrar”单身,并注册@PreDestroy。如果注册服务器处于关闭状态,它可以将该事件传播给任何剩余的会话范围的bean,这些bean仍然向其注册。

不理想,但务实的解决方案。

+0

好的建议,但真的会conf。 “这是一个错误?” – Nikita 2011-03-01 21:30:22

2

我想这是设计。

例如,Tomcat默认为每个已部署的应用程序将其会话存储在SESSIONS.ser中。如果关闭Tomcat并重新启动它,它会重新读取SESSIONS.ser。所以,我猜想就Spring而言,关闭容器并不一定意味着终止会话 - 这意味着@PreDestroy方法不会在会话范围的bean上调用。

相关问题