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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29169916/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 14:47:16  来源:igfitidea点击:

How correctly close the ApplicationContext in Spring?

javaspringspring-mvcapplicationcontext

提问by AndreaNobili

I am studying for the Spring Core certification and I have some dount about on this question finded into the provided study material:

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

What is the preferred way to close an application context?

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

I know that if I have something like this:

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

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

by the use of the close()method on the contextobjet the ApplicationContext is closed and the application is destroyed.

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

But I think that this is not the best way that I have to do it.

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

Reading the official documentation I find that I can also do something like this:

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

context.registerShutdownHook();

that register a Shutdown Hook with the JVMso it is the JVM that will trigger Spring's close phase before JVM exits. So on JVM exit, Spring's close phase will execute.

注册与JVM关闭挂钩所以它是JVM将JVM退出前扳机簧收盘阶段。所以在 JVM 退出时,Spring 的关闭阶段将执行。

On the documentation I can read that: usually not possible to call context.close()because many applications (web applications) run indefinitely But what exactly means this last assertion? why web application run indefinitely?

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

So my questions are:

所以我的问题是:

  • Can I use this second way to close an application context also with not web application?
  • Is it prefered respect the context.close()?
  • 我可以使用第二种方法来关闭非 Web 应用程序的应用程序上下文吗?
  • 它是首选尊重context.close()吗?

Tnx

田纳西州

回答by Arkantos

As you are aware that ContextLoaderListeneris the one that takes care of initializing and destroying your ApplicationContext, when you shutdown your server, that ContextLoaderListener's contextDestroyedmethod is invoked.

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

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

In that closeWebApplicationContext, they actually call the closemethod on ApplicationContext like this

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

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

This is straight from spring-web-4.1.5.jar. As it is evident from here, they use closeto destroy ApplicationContext in web applications.

这是直接来自spring-web-4.1.5.jar. 从这里可以看出,它们用于close销毁 Web 应用程序中的 ApplicationContext。

But registerShutdownHookis used to explicitly shut down IoC container in non-web applications something like a standalone desktop application, specially when you're creating the ApplicationContext manually from ClassPathXmlApplicationContext (or) FileSystemXmlApplicationContext (or) some other types.

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

This is done to release all resources used by your spring application and to call destroy method on your spring beans if any.

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

回答by Tunaki

On the documentation I can read that: usually not possible to call context.close() because many applications (web applications) run indefinitely But what exactly means this last assertion? why web application run indefinitely?

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

A web application will run as long as the application server that deploys it runs. It is up to the application server (and not to you) to correctly start and stop your application. This means that when the application server is stopped, the servlet context is destroyed. In a Spring application, the ContextLoaderListenerclass registered in web.xmllistens to this event (context destroyed) to properly close the Spring context.

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

When using Spring outside of an application server (like a standalone application), it is up to you to correctly stop the Spring context. As you said, this can be done by explicitly calling context.close()or registering a shutdown hook (context.registerShutdownHook()) that makes this call for you.

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