当我的tomcat关闭时,没有调用spring bean的destroy-method

Posted

技术标签:

【中文标题】当我的tomcat关闭时,没有调用spring bean的destroy-method【英文标题】:destroy-method of spring bean is not getting called when my tomcat shuts down 【发布时间】:2014-05-12 06:13:26 【问题描述】:

当我的应用程序在tomcat停止的情况下关闭时,我无法找到我的destroy-method没有被调用的原因。

我有一个 web 应用程序,spring 上下文正在通过 web.xml 中的 ContextLoaderListener 加载,如下所示:

web.xml

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:appContext.xml</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

下面是我的应用程序中的一个 Employee bean:

Employee.class

public class Employee 
    String eName;
    long eSal;
    public String getEName() 
        return eName;
    
    public void setEName(String name) 
        eName = name;
    
    public long getESal() 
        return eSal;
    
    public void setESal(long sal) 
        eSal = sal;
    

    public void init() 
        System.out.println("Initiaizing...");
        System.out.println("eName: " + eName + " - eSal: " + eSal);
    

    public void close() 
        System.out.println("Destroying...");
    

并且 bean 是在我的应用程序上下文文件中定义的,如下所示:

appContext.xml

<beans:beans xmlns="http://www.springframework.org/schema/integration"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.1.xsd">

    <beans:bean id="employee" class="com.test.Employee" init-method="init" destroy-method="close">
        <beans:property name="eName" value="sandip" />
        <beans:property name="eSal" value="80000" />
    </beans:bean>        
</beans:beans>

Tomcat 控制台日志:

May 12, 2014 11:28:46 AM org.apache.catalina.core.AprLifecycleListener init
INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\Program Files\Java\jre6\bin;.;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Program Files\Java\jre7\bin\client;C:\Program Files\Java\jre7\bin;C:\Program Files\Common Files\NetSarang;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Lenovo\Access Connections\;D:\Project\maven-2.0.7\bin;D:\Software Backup\apache-ant-1.7.0\bin;C:\Program Files\Java\jdk1.6.0_20\bin;D:\Project\OBD3\1.5;D:\Software Backup\CVS;D:\Project\UNIX\UnxUtils\usr\local\wbin;C:\Program Files\QuickTime\QTSystem\;D:\Personal\MongoDB\MongoDB_work\mongodb\bin;D:\Software Installed\MariaDB 5.5\bin;C:\Program Files\Git\bin
May 12, 2014 11:28:46 AM org.apache.tomcat.util.digester.SetPropertiesRule begin
WARNING: [SetPropertiesRule]Server/Service/Engine/Host/Context Setting property 'source' to 'org.eclipse.jst.jee.server:testSpringBeanDestroy' did not find a matching property.
May 12, 2014 11:28:46 AM org.apache.coyote.http11.Http11Protocol init
INFO: Initializing Coyote HTTP/1.1 on http-8093
May 12, 2014 11:28:46 AM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 419 ms
May 12, 2014 11:28:46 AM org.apache.catalina.core.StandardService start
INFO: Starting service Catalina
May 12, 2014 11:28:46 AM org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/6.0.32
May 12, 2014 11:28:46 AM org.apache.catalina.loader.WebappClassLoader validateJarFile
INFO: validateJarFile(D:\Project\Workspace_new\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\testSpringBeanDestroy\WEB-INF\lib\servlet.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class
May 12, 2014 11:28:46 AM org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring root WebApplicationContext
log4j:WARN No appenders could be found for logger (org.springframework.web.context.ContextLoader).
log4j:WARN Please initialize the log4j system properly.
Initiaizing...
eName: sandip - eSal: 80000
May 12, 2014 11:28:47 AM org.apache.coyote.http11.Http11Protocol start
INFO: Starting Coyote HTTP/1.1 on http-8093
May 12, 2014 11:28:47 AM org.apache.jk.common.ChannelSocket init
INFO: JK: ajp13 listening on /0.0.0.0:8011
May 12, 2014 11:28:47 AM org.apache.jk.server.JkMain start
INFO: Jk running ID=0 time=0/20  config=null
May 12, 2014 11:28:47 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 768 ms

当我启动我的 tomcat 时,我可以看到我的 init 方法被调用,但不幸的是,当我停止 tomcat 时 close() 即没有调用destroy方法。

我正在使用 spring 3.1.2 分发罐。

我做错了什么?

【问题讨论】:

如何停止 Tomcat? 直接杀掉进程或者使用shutdown.sh 你在 kill 和 shutdown.sh 中得到相同的行为?我原以为只有 kill 不会按预期工作。 是的.. 两种情况的行为相同。 尝试查看是否在tomcat关闭期间调用了ContextLoaderListener.contextDestroyed。 【参考方案1】:

谢谢安德烈。为你+1。 问题是我没有正确关闭。现在,在阅读了一些文档后,我发现如果我从 Tomcat 管理器或使用关闭脚本(如 (shutdwon.sh/shutdown.bat))优雅地关闭我的 tomcat,我的销毁方法就会被调用。

Kill -9 命令不起作用,如果试图从 Eclipse 中停止,它也不起作用。

【讨论】:

我也有类似的情况。我希望我的 Servlet 的 destroy() 方法被触发,并且能够在 Tomcat7 服务停止时运行完成(service tomcat7 stop),但我不知道这是否是正确的方法。在哪里可以找到关闭脚本? (shutdown.sh/shutdown.bat)? service tomcat7 stop 应该等效还是不调用 destroy() 想特别引起你的注意@Sandy

以上是关于当我的tomcat关闭时,没有调用spring bean的destroy-method的主要内容,如果未能解决你的问题,请参考以下文章

我的 spring+hibernate 应用程序没有关闭 jdbc 连接

Spring Boot 入门 404 错误

用于 Spring 和 Angular 应用程序的 Nginx 和 Tomcat

当我打开visualvm分析器时tomcat关闭

如何在外部 tomcat 中部署 Spring-boot REST API

中止Tomcat初创公司