我正在学习Spring Core认证,在提供的学习材料中,我对这个问题有一些疑问:
关闭应用程序上下文的首选方法是什么?
我知道如果我有这样的东西:
ConfigurableApplicationContext context = …
// Destroy the application
context.close();
通过在上下文对象上使用close()方法,ApplicationContext被关闭,应用程序被销毁。
但我认为这不是我必须做的最好的方式。
阅读官方留档,我发现我也可以这样做:
context.registerShutdownHook();
在JVM中注册一个关闭挂钩,因此JVM将在JVM退出之前触发Spring的关闭阶段。所以在JVM退出时,将执行Spring的关闭阶段。
在留档上,我可以读到:通常不可能调用context.close()
,因为许多应用程序(Web应用程序)无限期运行但是最后一个断言到底是什么意思?为什么Web应用程序无限期运行?
所以我的问题是:
Tnx公司
从…起https://stackoverflow.com/a/42018369:
Application ationContext
类没有将这些方法中的任何一个定义为其接口的一部分,但ConfigurableApplication ationContext
确实定义了这两个方法。
从JavaDoc:
<代码>关闭()--关闭此应用程序上下文,销毁其bean工厂中的所有beanregisterShutdownHook()
--在JVM运行时注册一个关闭钩子,在JVM关闭时关闭此上下文,除非此时它已经关闭。基本上,AbstractApplicationContext#close()
将在调用时关闭或关闭ApplicationContext,而
AbstractApplicationContext#registerShutdownHook()
将在稍后JVM出于任何原因关闭时关闭或关闭ApplicationContext。这将通过利用JVM关闭挂钩功能来实现。
在任何一种情况下,实际的关闭都是通过
doClose()
方法完成的。
如果您想知道为什么输出看起来如此相似,那是因为它们实际上在做相同的事情,无论您在示例的第3行调用
将在JVM退出之前关闭,这几乎是在调用完方法后立即关闭,因为它是最后一行代码!close()
还是registerShutdownHook()
close()
将立即关闭,而registerShutdownHook()
在留档上,我可以读到:通常不可能调用context.close(),因为许多应用程序(Web应用程序)无限期运行但是最后一个断言到底是什么意思?为什么Web应用程序无限期运行?
只要部署web应用程序的应用程序服务器运行,web应用程序就会一直运行。正确启动和停止应用程序取决于应用程序服务器(而不是您)。这意味着当应用服务器停止时,servlet上下文将被破坏。在Spring应用程序中,在web中注册的ContextLoaderListener类。xml侦听此事件(上下文已破坏)以正确关闭Spring上下文。
在应用程序服务器(如独立应用程序)之外使用Spring时,正确停止Spring上下文取决于您。如您所述,这可以通过显式调用context.close()
或注册一个关闭挂钩(context.registerShutdown Hook()
)来完成。
正如您所知,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方法。 那么代码应该是什么样的呢?