@PreDestroy、destroyMethod 和 disposableBean.destroy() 在什么时候执行?

huangapple go评论78阅读模式
英文:

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.");
    }
}

以下是您的问题的翻译:

  1. 除了显式调用context.close()之后(我敢大胆猜测,在生产代码中不经常发生),这些回调函数什么时候触发?如果Spring使用类似下面的方式注册这些回调函数:
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
    // 销毁方法的逻辑
}));

我得到了答案,但我不确定这是否是实际发生的情况。

  1. 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):

  1. 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

  1. 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将最后被销毁。

接下来有一个关于销毁方法顺序调用的问题,因为有多种不同的方法。这在文档中中有明确定义:

销毁方法按照以下顺序调用:

  1. 使用@PreDestroy注解的方法
  2. DisposableBean回调接口定义的destroy()方法
  3. 自定义配置的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

huangapple
  • 本文由 发表于 2023年7月18日 09:09:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/76708959.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定