使用Spring 3.0.5 GA
使用@PreDestroy方法创建一个会话范围的bean。注意到如果拥有HttpSession超时(即超过Servlet容器的会话超时值),则会发出@PreDestroy回调。但是,如果我只是关闭app服务器,则不会调用@PreDestroy。这是设计还是错误?如果是后者,有任何关于解决方案的建议吗?
FWIW,在两种情况下都会调用单个bean上的@PreDestroy。
感谢, -nikita
PS。有一个可能相关的Spring bug - SPR-7359
答案 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上调用。