当前位置: 首页 > 知识库问答 >
问题:

如何在Spring中正确关闭ApplicationContext?

王曜文
2023-03-14

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

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

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

ConfigurableApplicationContext context = …
// Destroy the application
context.close();

通过在上下文对象上使用close()方法,ApplicationContext被关闭,应用程序被销毁。

但我认为这不是我必须做的最好的方式。

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

context.registerShutdownHook();

在JVM中注册一个关闭挂钩,因此JVM将在JVM退出之前触发Spring的关闭阶段。所以在JVM退出时,将执行Spring的关闭阶段。

在留档上,我可以读到:通常不可能调用context.close(),因为许多应用程序(Web应用程序)无限期运行但是最后一个断言到底是什么意思?为什么Web应用程序无限期运行?

所以我的问题是:

  • 我是否可以使用第二种方法关闭应用程序上下文,而不是关闭web应用程序
  • 是否更倾向于尊重上下文。关闭()

Tnx公司

共有3个答案

燕禄
2023-03-14

从…起https://stackoverflow.com/a/42018369:

Application ationContext类没有将这些方法中的任何一个定义为其接口的一部分,但ConfigurableApplication ationContext确实定义了这两个方法。

从JavaDoc:

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

在任何一种情况下,实际的关闭都是通过doClose()方法完成的。

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

陆运乾
2023-03-14

在留档上,我可以读到:通常不可能调用context.close(),因为许多应用程序(Web应用程序)无限期运行但是最后一个断言到底是什么意思?为什么Web应用程序无限期运行?

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

在应用程序服务器(如独立应用程序)之外使用Spring时,正确停止Spring上下文取决于您。如您所述,这可以通过显式调用context.close()或注册一个关闭挂钩(context.registerShutdown Hook())来完成。

蒋泰
2023-03-14

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

  public void contextDestroyed(ServletContextEvent event){
    closeWebApplicationContext(event.getServletContext());
    ContextCleanupListener.cleanupAttributes(event.getServletContext());
  }

在这种情况下,他们实际上在ApplicationContext上调用了方法

  if ((this.context instanceof ConfigurableWebApplicationContext)) {
    ((ConfigurableWebApplicationContext)this.context).close();
  }

这直接来自spring-web-4.1.5。jar。从这里可以明显看出,他们使用close来破坏web应用程序中的ApplicationContext。

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

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

 类似资料:
  • 问题内容: 我有全部传播异常的方法,然后在一个地方处理,但是我意识到了一些事情。 假设我有这样的方法 我的问题是,如果doSometing()方法引发异常,该语句将不会关闭,但我不想在那里处理异常。尝试并捕获只会抛出异常并最终关闭语句的正确方法吗? 问题答案:

  • 问题内容: 在清理一些代码时,FindBugs向我介绍了一些使用Connection,CallableStatement和ResultSet对象的JDBC代码。这是该代码的一个片段: FindBugs指出这些应该在finally块内。我开始重构我的代码来做到这一点,我开始想知道如何在finally块中处理代码。 Connection对象的CallableStatement的创建可能会引发异常,而我

  • 问题内容: 其中哪一个是正确的? 问题答案: 工作正常,并正确关闭标签。最好为视障人士添加属性。

  • 问题内容: 如何正确关闭IPython Notebook? 目前,我只是关闭浏览器选项卡,然后在终端中使用。 不幸的是,滴答也无济于事(它们确实杀死了它们的内核,但没有退出iPython)。 问题答案: 当前没有比终端中的Ctrl + C更好的方法了。 我们正在考虑如何进行显式关机,但是笔记本作为单用户应用程序(用户可以自由停止它)和作为多用户服务器(只能由管理员操作)之间存在一些紧张关系。阻止它

  • 我有一个简单的java,它运行一些任务对象(实现)。 除了尽最大努力尝试停止处理正在执行的任务之外,没有任何保证。例如,典型的实现将通过{@link thread#interrupt}取消,因此任何未能响应中断的任务都可能永远不会终止。 我的问题是,有没有办法确保那些(任务)线程会终止?我想出的最佳解决方案是在程序末尾调用,但这显然是愚蠢的。

  • 想改进这个问题吗 通过编辑此帖子,更新问题,使其只关注一个问题。 我不想将任何参数传递给AsyncTask的doInBackground方法。 那么代码应该是什么样的呢?