如何在Spring中正确关闭ApplicationContext?

And*_*ili 9 java spring spring-mvc applicationcontext

我正在攻读Spring Core认证,我对提供的学习资料中的这个问题有一些了解:

关闭应用程序上下文的首选方法是什么?

我知道如果我有这样的事情:

ConfigurableApplicationContext context = …
// Destroy the application
context.close();
Run Code Online (Sandbox Code Playgroud)

通过在context objet 上使用close()方法,ApplicationContext被关闭并且应用程序被销毁.

但我认为这不是我必须做的最佳方式.

阅读官方文档,我发现我也可以这样做:

context.registerShutdownHook();
Run Code Online (Sandbox Code Playgroud)

注册与JVM关闭挂钩,因此是将触发Spring的密切相JVM退出之前的JVM.所以在JVM退出时,Spring的关闭阶段将会执行.

在文档中,我可以读到:通常无法调用,context.close()因为许多应用程序(Web应用程序)无限期运行但是这最后一个断言究竟意味着什么?为什么Web应用程序无限期运行?

所以我的问题是:

  • 我是否可以使用第二种方式关闭应用程序上下文而不是Web应用程序?
  • 是否优先尊重context.close()

TNX

Ark*_*tos 12

如您所知,这ContextLoaderListener是一个负责初始化和销毁​​ApplicationContext的工作,当您关闭服务器时,contextDestroyed会调用ContextLoaderListener的方法.

  public void contextDestroyed(ServletContextEvent event){
    closeWebApplicationContext(event.getServletContext());
    ContextCleanupListener.cleanupAttributes(event.getServletContext());
  }
Run Code Online (Sandbox Code Playgroud)

在那closeWebApplicationContext,他们实际上close像这样调用ApplicationContext上的方法

  if ((this.context instanceof ConfigurableWebApplicationContext)) {
    ((ConfigurableWebApplicationContext)this.context).close();
  }
Run Code Online (Sandbox Code Playgroud)

这是直截了当的spring-web-4.1.5.jar.从这里可以看出,它们用于close在Web应用程序中销毁ApplicationContext.

但是registerShutdownHook用于显式关闭非Web应用程序中的IoC容器,就像独立的桌面应用程序一样,特别是当您从ClassPathXmlApplicationContext(或)FileSystemXmlApplicationContext(或)其他一些类型手动创建ApplicationContext时.

这样做是为了释放spring应用程序使用的所有资源,并在你的spring bean上调用destroy方法(如果有的话).


Tun*_*aki 8

在文档中我可以读到:通常不可能调用context.close(),因为许多应用程序(Web应用程序)无限期地运行但是这最后一个断言究竟意味着什么?为什么Web应用程序无限期运行?

只要部署它的应用程序服务器运行,Web应用程序就会运行.由应用程序服务器(而不是您)来正确启动和停止应用程序.这意味着当应用程序服务器停止时,servlet上下文将被销毁.在Spring应用程序中,ContextLoaderListener注册的类会web.xml侦听此事件(已销毁的上下文)以正确关闭Spring上下文.

在应用程序服务器外部使用Spring(如独立应用程序)时,您可以正确停止Spring上下文.如你所说,这可以通过显式调用context.close()或注册一个context.registerShutdownHook()为你调用的shutdown hook()来完成.