Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在Spring中正确关闭ApplicationContext?_Java_Spring_Spring Mvc_Applicationcontext - Fatal编程技术网

Java 如何在Spring中正确关闭ApplicationContext?

Java 如何在Spring中正确关闭ApplicationContext?,java,spring,spring-mvc,applicationcontext,Java,Spring,Spring Mvc,Applicationcontext,我正在学习Spring Core认证,在提供的学习材料中,我对这个问题有一些疑问: 关闭应用程序上下文的首选方式是什么 我知道如果我有这样的东西: ConfigurableApplicationContext context = … // Destroy the application context.close(); context.registerShutdownHook(); 通过在上下文对象上使用close()方法,ApplicationContext被关闭,应用程序被销毁 但我认为

我正在学习Spring Core认证,在提供的学习材料中,我对这个问题有一些疑问:

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

我知道如果我有这样的东西:

ConfigurableApplicationContext context = …
// Destroy the application
context.close();
context.registerShutdownHook();
通过在上下文对象上使用close()方法,ApplicationContext被关闭,应用程序被销毁

但我认为这不是我做这件事的最好方式

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

ConfigurableApplicationContext context = …
// Destroy the application
context.close();
context.registerShutdownHook();
在JVM中注册一个关闭钩子,因此JVM将在JVM退出之前触发Spring的关闭阶段。所以在JVM退出时,将执行Spring的关闭阶段

在文档中我可以读到:通常不可能调用
context.close()
,因为许多应用程序(web应用程序)无限期运行,但这最后一个断言的确切含义是什么?为什么web应用程序无限期运行

因此,我的问题是:

  • 我是否可以使用第二种方法关闭应用程序上下文,而不是关闭web应用程序
  • 是否优先考虑
    上下文.close()
Tnx

在文档中我可以读到:通常不可能调用context.close(),因为许多应用程序(web应用程序)无限期运行,但最后一个断言的确切含义是什么?为什么web应用程序无限期运行

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


在应用服务器之外使用Spring时(如独立应用程序),正确停止Spring上下文取决于您。正如您所说,这可以通过显式调用
context.close()
或注册一个为您进行此调用的关闭钩子(
context.registerSutdownhook()
)来实现。

正如您所知,
ContextLoaderListener
负责初始化和销毁您的应用程序上下文,关闭服务器时,将调用ContextLoaderListener的
contextDestroyed
方法

  public void contextDestroyed(ServletContextEvent event){
    closeWebApplicationContext(event.getServletContext());
    ContextCleanupListener.cleanupAttributes(event.getServletContext());
  }
closeWebApplicationContext
中,他们实际上在ApplicationContext上调用
close
方法,如下所示

  if ((this.context instanceof ConfigurableWebApplicationContext)) {
    ((ConfigurableWebApplicationContext)this.context).close();
  }
这直接来自
spring-web-4.1.5.jar
。从这里可以明显看出,他们使用
close
销毁web应用程序中的应用程序上下文

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

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

来自:

ApplicationContext
类没有将这两种方法定义为其接口的一部分,但是
ConfigurableApplicationContext
确实定义了这两种方法

从JavaDoc:

close()
——关闭此应用程序上下文,销毁其bean工厂中的所有bean。
registerShutdownHook()
——在JVM运行时注册一个关闭钩子,在JVM关闭时关闭此上下文,除非当时它已经关闭。 基本上,
AbstractApplicationContext#close()
将在调用时关闭
ApplicationContext
,而
AbstractApplicationContext#registerSuttonHook()
将在稍后JVM出于任何原因关闭时关闭或关闭
ApplicationContext
。这将通过利用JVM关闭挂钩功能来实现

在这两种情况下,实际关闭都是通过
doClose()
方法完成的


如果您想知道为什么您的输出看起来如此相似,那是因为它们实际上在做相同的事情,无论您在示例的第3行调用
close()
还是
registerShutdownHook()
close()
将立即关闭,
registerShutdownHook()
将在JVM退出之前关闭,这几乎是在调用该方法后立即关闭,因为它是最后一行代码

许多应用程序(web应用程序)无限期运行
。它通常指在无限循环中发生的事情,除非您停止该过程,例如您的SocketServer侦听传入请求。首先,为什么要手动关闭WebApplicationContext?它通常是在服务器启动时创建的,在服务器关闭时销毁。web应用程序永远不会停止,因为如果这样做,站点就会关闭。若要停止运行web应用程序,将关闭它(例如,通过停止web服务器)。当您这样做时,JVM也会停止,因此“关闭JVM的钩子”是关闭JVM上下文的方法。为什么要停止上下文?close用于web应用程序,而shutDownHook用于独立应用程序。刚刚发布了我的答案,但没有更多细节:)好的,但是它是context.registerShutdownHook()比context.close()好吗?和方法都调用相同的代码来关闭Spring上下文。您可以在
AbstractApplicationContext
中看到这一点。在独立应用程序中,例如后台服务或桌面应用程序,当您输入main方法时,您将创建应用程序上下文,现在我的问题是,如果您注册