我正在攻读Spring Core认证,我对这个提供的学习材料中的问题有一些了解:
关闭应用程序上下文的首选方法是什么?
我知道如果我有这样的事情:
ConfigurableApplicationContext context = …
// Destroy the application
context.close();
通过在上下文对象上使用 close()方法,关闭ApplicationContext并销毁应用程序。
但我认为这不是我必须做的最佳方式。
阅读官方文档我发现我也可以这样做:
context.registerShutdownHook();
使用JVM注册Shutdown Hook ,因此JVM将在JVM退出之前触发Spring的关闭阶段。所以在JVM退出时,Spring的关闭阶段将会执行。
在文档中,我可以读到:通常无法调用context.close()
,因为许多应用程序(Web应用程序)无限期运行但是这最后一个断言的确切意味着什么?为什么Web应用程序无限期运行?
所以我的问题是:
context.close()
?TNX
答案 0 :(得分:11)
如您所知ContextLoaderListener
是负责初始化和销毁ApplicationContext的那个,当您关闭服务器时,会调用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应用程序中的ApplicationContext。
但是registerShutdownHook
用于显式关闭非Web应用程序中的IoC容器,就像独立的桌面应用程序一样,特别是当您从ClassPathXmlApplicationContext(或)FileSystemXmlApplicationContext(或)手动创建ApplicationContext时其他类型。
这样做是为了释放spring应用程序使用的所有资源,并在你的spring bean上调用destroy方法(如果有的话)。
答案 1 :(得分:8)
在文档上我可以读到:通常无法调用context.close(),因为许多应用程序(Web应用程序)无限期地运行但是这最后一个断言的确切含义是什么?为什么Web应用程序无限期运行?
只要部署它的应用程序服务器运行,Web应用程序就会运行。由应用程序服务器(而不是您)来正确启动和停止应用程序。这意味着当应用程序服务器停止时,servlet上下文将被销毁。在Spring应用程序中,web.xml
中注册的ContextLoaderListener
类侦听此事件(已销毁的上下文)以正确关闭Spring上下文。
在应用程序服务器外部使用Spring(如独立应用程序)时,您可以正确停止Spring上下文。正如您所说,这可以通过显式调用context.close()
或注册一个为您调用此函数的关闭挂钩(context.registerShutdownHook()
)来完成。
答案 2 :(得分:0)
来自https://stackoverflow.com/a/42018369:
ApplicationContext
类并未将这两种方法中的任何一种定义为其接口的一部分,但是ConfigurableApplicationContext
确实定义了这两种方法。
来自JavaDoc:
close()
-关闭此应用程序上下文,销毁其bean工厂中的所有bean。registerShutdownHook()
-在JVM运行时中注册一个关闭挂钩,除非当时已经关闭了该上下文,否则在JVM关闭时将其关闭。 基本上,AbstractApplicationContext#close()
将在调用时关闭或关闭ApplicationContext
,而AbstractApplicationContext#registerShutdownHook()
将在以后的某个时间关闭或关闭ApplicationContext
。 JVM由于任何原因而关闭。这将通过利用JVM关闭挂钩功能来实现。
在任何一种情况下,实际关闭都是通过doClose()
方法完成的。
如果您对输出为何如此相似感到好奇,那是因为无论您在示例的第3行中调用close()
还是registerShutdownHook()
,它们都在有效地完成相同的事情。 close()
将立即关闭,而registerShutdownHook()
将在JVM退出之前关闭,这几乎是在方法被调用后立即关闭,因为这是最后一行代码!>