java 如何在PreDestroy之前注册Springs SIGTERM正常关闭同步方法?

ovfsdjhp  于 2023-02-28  发布在  Java
关注(0)|答案(1)|浏览(120)

Springs允许使用@PreDestroy注解注册多个pre-destroy钩子,这对于清除资源非常有用。
我们有多个不同的模块,每个模块都与不同的数据库连接相关。在每个模块中,我们使用@Bean(destroyMethod = "shutdown")或使用@PreDestroy注解的单独方法为每个数据库连接定义destroy方法,以实现更复杂的关闭过程。
我们还有多个与端点实现相关的模块(如gRPC端点、GraphQL端点、REST端点模块)。
我们希望为使用这些端点的应用程序添加正常关机流程。正常关机指的是如下流程:
1.首先关闭端点服务器(即拒绝任何新连接,但等待当前连接完成)。即需要关闭以下端点服务器并等待关闭过程完成:一米六氮一x一米七氮一x一米八氮一x。
1.只有在步骤1.完全完成之后,我们才应该触发bean销毁方法(即,使用@PreDestroy注解并通过destroyMethod指定的方法)。
如何正确地注入SIGTERM信号的所有其他钩子之前调用的特定钩子?
我认为我们可能错误地使用了@PreDestroy,因为我们正在寻找的功能是@PrePreDestroy,这听起来很愚蠢。
旁注:server.shutdown=graceful不是我们的选项,因为我们使用的是自定义服务器,而不是默认的嵌入式服务器。

5jdjgkvh

5jdjgkvh1#

经过一点实验,我发现ContextClosedEvent上的ApplicationListener总是在调用任何@PreDestroy方法或任何bean的destroyMethod之前执行,也就是说,总是先调用onApplicationEvent(ContextClosedEvent event)
一个例子是:

@Component
public class PriorityShutdownListener implements ApplicationListener<ContextClosedEvent> {
    
    @Autowired
    private Server grpcServer;
    
    /**
     * This blocking code will be executed before any 
     * @PreDestroy method or bean's `destroyMethod` is called.
     */
    @Override
    public void onApplicationEvent(ContextClosedEvent event) {
        grpcServer.shutdown();
        // don't forget to await for existing
        // calls to finish before returning from this method
    }
}

相关问题