在tomcat关闭时没有在会话范围的Spring bean上调用@PreDestroy

时间:2011-03-01 20:35:43

标签: spring session tomcat

使用Spring 3.0.5 GA

使用@PreDestroy方法创建一个会话范围的bean。注意到如果拥有HttpSession超时(即超过Servlet容器的会话超时值),则会发出@PreDestroy回调。但是,如果我只是关闭app服务器,则不会调用@PreDestroy。这是设计还是错误?如果是后者,有任何关于解决方案的建议吗?

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

感谢, -nikita

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

2 个答案:

答案 0 :(得分:6)

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

如果这对你来说是一个噱头,你可能会考虑让scoped bean在@PostConstruct期间注册一个“注册商”单身,并在@PreDestroy注销自己。如果注册商已关闭,它可以将该事件传播到仍在其中注册的任何剩余会话范围的bean。

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

答案 1 :(得分:2)

我猜这是设计的。

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