Java 如何在终止之前为容器中的每个bean调用destroy方法

Java 如何在终止之前为容器中的每个bean调用destroy方法,java,spring,Java,Spring,我目前正在学习和试验Spring的init方法和销毁方法属性,这些属性是在Spring配置中指定的 我的问题是,在程序终止之前,如何让Spring为那些设置了方法的bean调用destroy方法? 换句话说,我希望在程序存在于执行中之前,对所有具有destroy方法属性的bean执行任何分解操作。这可能吗 正如许多其他人所建议的,我正在阅读曼宁的书《行动中的春天》,因此我现在正在试验这种豆子: <bean id="auditorium" class="com.springinaction

我目前正在学习和试验Spring的init方法和销毁方法属性,这些属性是在Spring配置中指定的

我的问题是,在程序终止之前,如何让Spring为那些设置了方法的bean调用destroy方法?

换句话说,我希望在程序存在于执行中之前,对所有具有destroy方法属性的bean执行任何分解操作。这可能吗

正如许多其他人所建议的,我正在阅读曼宁的书《行动中的春天》,因此我现在正在试验这种豆子:

 <bean id="auditorium" class="com.springinaction.springidol.Auditorium"
 init-method="turnOnLights"
  destroy-method="turnOffLights"/>
此外,为了回答一个完整的问题,下面是我在礼堂上的课:

public class Auditorium {

    private boolean isLightsOn;

    public Auditorium() {
        isLightsOn = false;
    }

    public void turnOnLights() {
        isLightsOn = true;
        printLights();
    }

    public void turnOffLights() {
        isLightsOn = false;
        printLights();
    }

    public void printLights() {
        if (isLightsOn) {
            System.out.println("Lights are turned on!");
        } else {
            System.out.println("Lights are turned off!");
        }
    }
}

当上下文为或时,将调用所有
destroy
方法。如果运行独立应用程序,为了确保在应用程序结束之前调用destroy方法,您需要

所有这些方法都可以在
ConfigurableApplicationContext
界面中使用,因此您需要使用它,而不仅仅是
ApplicationContext
(您将要使用的几乎所有上下文都将实现此界面,因此您无需担心):


在应用程序服务器等非独立(托管)场景中,关闭/刷新上下文会在关闭/重新部署时自动发生,因此您无需执行任何操作。

Cool it works..shutdown hook与在代码终止前关闭有什么区别吗?是的,shutdown hook更可靠;如果从终端使用Ctrl-C关闭应用程序,将执行关闭钩子,但很可能永远不会到达
close()
调用。应用程序服务器通常依靠关闭挂钩来正确终止(除非
kill-9
切断它们的连接)。最终,spring应用程序上下文的关闭钩子只不过是调用
doClose()
,但它的执行是由JVM保证的。没问题。再想一想,由于您正在进行实验,您可能会发现需要
close()
refresh()
您的上下文而不需要任何关闭挂钩,只需跟踪行为即可。上面的建议更多的是生产设置建议,可能不是您玩游戏所需要的。您提到在托管场景中,关闭/刷新上下文会自动发生。我在ElasticBeanstalk上运行Tomcat中的一个应用程序,我根本没有看到任何关闭挂钩被触发。所有的启动都是,但关机不是。我想知道ElasticBeanstalk在更新/重新部署时是否做了一些非标准的事情。有什么想法吗?在servlet容器(本例中为tomcat)等托管场景中,您需要依赖servlet上下文生命周期,而不是关闭挂钩(仅在tomcat关闭时启动,而不是在webapp重新部署时启动)。Spring为此提供了一个名为
ContextLoaderListener
的实用程序类,您需要在
web.xml
中将其配置为
public class Auditorium {

    private boolean isLightsOn;

    public Auditorium() {
        isLightsOn = false;
    }

    public void turnOnLights() {
        isLightsOn = true;
        printLights();
    }

    public void turnOffLights() {
        isLightsOn = false;
        printLights();
    }

    public void printLights() {
        if (isLightsOn) {
            System.out.println("Lights are turned on!");
        } else {
            System.out.println("Lights are turned off!");
        }
    }
}
ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("Beans.xml");
ctx.registerShutdownHook(); // this should be it, destroys are called before your app exits