英文:
At what point are @PreDestroy, destroyMethod, and disposableBean.destroy() executed?
问题
@PreDestroy
注解:
@Component
public class Bean1 {
@PreDestroy
public void destroy() {
System.out.println("Callback triggered - @PreDestroy.");
}
}
destroyMethod
:
public class Bean3 {
public void destroy() {
System.out.println("Callback triggered - bean destroy method.");
}
}
ShutdownHookConfiguration
配置类:
@Configuration
public class ShutdownHookConfiguration {
@Bean(destroyMethod = "destroy")
public Bean3 initializeBean3() {
return new Bean3();
}
}
DisposableBean.destroy()
方法:
@Component
public class Bean2 implements DisposableBean {
@Override
public void destroy() throws Exception {
System.out.println("Callback triggered - DisposableBean.");
}
}
以下是您的问题的翻译:
- 除了显式调用
context.close()
之后(我敢大胆猜测,在生产代码中不经常发生),这些回调函数什么时候触发?如果Spring使用类似下面的方式注册这些回调函数:
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
// 销毁方法的逻辑
}));
我得到了答案,但我不确定这是否是实际发生的情况。
-
Spring是否保证这些回调函数的执行顺序(理论上,我可以使用每种方式提供单独的销毁方法,而这些实现可能彼此依赖)?再次,如果Spring使用
addShutdownHook()
添加一个关闭挂钩,我得到了答案,因为该方法的文档明确说明:当虚拟机开始其关闭序列时,它将以某种未指定的顺序启动所有注册的关闭挂钩,并让它们并发运行。
但我不确定这是否是实际发生的情况。
英文:
You can use either of these to define a method to be executed right before bean destruction (examples are borrowed from Baeldung):
@PreDestroy
@Component
public class Bean1 {
@PreDestroy
public void destroy() {
System.out.println(
"Callback triggered - @PreDestroy.");
}
}
destroyMethod
:
public class Bean3 {
public void destroy() {
System.out.println(
"Callback triggered - bean destroy method.");
}
}
@Configuration
public class ShutdownHookConfiguration {
@Bean(destroyMethod = "destroy")
public Bean3 initializeBean3() {
return new Bean3();
}
}
and disposableBean.destroy()
:
@Component
public class Bean2 implements DisposableBean {
@Override
public void destroy() throws Exception {
System.out.println(
"Callback triggered - DisposableBean.");
}
}
I have these questions (I hope it's not too broad):
- When are these callbacks triggered other than after an explicit
context.close()
invocation (which, I'll venture to suggest, doesn't happen often in production code)? If Spring registers those callbacks with something like
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
// destroy method logic
}));
I got my answer, but I'm not sure it's what actually happens
- Does Spring guarantee any order of execution of those callbacks (theoretically, I can provide a separate destroy method using each of those ways, and the implementations may be interdependent)? Again, if Spring adds a shutdown hook with
addShutdownHook()
, I got my answer since the method's documentation explicitly says
> When the virtual machine begins its shutdown sequence it will start all registered shutdown hooks in some unspecified order and let them run concurrently.
but I'm not sure it's what actually happens
答案1
得分: 2
Spring将仅注册1个关闭挂钩,该挂钩将简单关闭ApplicationContext
,以确保它正确关闭。它通过简单地调用close
方法(或者是内部的doClose()
方法)来实现这一点,这确保了上下文的优雅关闭。
Bean的销毁顺序与它们创建的顺序相反,因此首先创建的Bean将最后被销毁。
接下来有一个关于销毁方法顺序调用的问题,因为有多种不同的方法。这在文档中中有明确定义:
销毁方法按照以下顺序调用:
- 使用
@PreDestroy
注解的方法- 由
DisposableBean
回调接口定义的destroy()
方法- 自定义配置的
destroy()
方法
英文:
Spring will register only 1 shutdown hook, which will simply close the ApplicationContext
so it can shutdown properly. It does this by simply calling the close
method (or rather the internal doClose()
method) this ensures a graceful shutdown of the context.
The beans are destroyed in the reverse order as they were created, so the bean that got created the first will be destroyed the last.
Next there is the question of the destroy methods order invocation as there are multiple flavors. This is clearly described in the documentation
> Destroy methods are called in the same order:
>
> 1. Methods annotated with @PreDestroy
> 2. destroy()
as defined by the DisposableBean
callback interface
> 3. A custom configured destroy()
method
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论