如何在启动关闭挂钩之前防止Spring应用程序上下文关闭 [英] How to prevent Spring app context shutdown until shutdown hook is fired

查看:108
本文介绍了如何在启动关闭挂钩之前防止Spring应用程序上下文关闭的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个spring-boot应用程序.

I have a spring-boot application.

我已经实现了 我的bean中的SmartLifecycle 接口可在 start 方法中启动异步snmp服务器,并在 stop 方法中将其停止.

I have implemented SmartLifecycle interface in my bean which starts async snmp server in it's start method and stops it in it's stop method.

一切正常,除了主应用程序上下文在启动后立即停止的事实之外,因此我的服务器bean在启动后也立即停止.

All working fine, except the fact that main application context stops right after start, so my server bean also stops right after start.

我需要做的是使spring上下文仅在关闭shutdown钩子被触发时才停止.

All I need is to make spring context to stop only when shutdown hook is fired.

这不是Web应用程序,因此我不需要 spring-boot-starter-web ,这可以通过启动webserver来解决此问题,这可以防止上下文停止直到webserver停止.

This is not a web application, so I don't need spring-boot-starter-web, which is solves this problem by starting webserver which prevents context stop until webserver stops.

我可以使用类似 CountDownLatch 之类的东西,并在上下文开始后立即在我的 main 方法中等待它为零.像这样的东西:

I can use something like CountDownLatch and waiting for it to be zero in my main method right after context starts. Somethig like this:

public static void main(String[] args) throws InterruptedException {
    ConfigurableApplicationContext ctx = SpringApplication.run(SnmpTrapRetranslatorApplication.class, args);
    CountDownLatch snmpServerCloseLatch = ctx.getBean("snmpServerCloseLatch", CountDownLatch.class);
    snmpServerCloseLatch.await();
}

然后我的服务器bean的 start 方法将创建一个计数为 1 的闩锁,而 stop 方法将调用 snmpServerCloseLatch.countDown().

And my server bean's start method will create this latch with count 1, while stop method will call snmpServerCloseLatch.countDown().

此处对此技术进行了说明.

This technique is described here.

但是这有什么问题,我的 main 方法负责等待我的自定义服务器bean停止.我觉得这不对.

But what wrong with this is that my main method is responsible for waiting my custom server bean to stop. I feel this just not right.

例如 spring-boot-starter-web 如何做到这一点?当它启动tomcat时,它将一直运行直到收到关闭钩子为止,并且在 main 方法中不需要任何管理代码.仅当上下文接收到关机信号时,它才会停止.

How for example spring-boot-starter-web do this? When it starts tomcat, it keeps running until shutdown hook is received and it don't need to have any managing code in the main method. It stops only when context receiving shoutdown signal.

例如,当我在bean中具有 @Scheduled 方法时,就会出现相同的行为.Spring也不会自动停止上下文.仅在 CTRL-C 上.

The same behaviour is for example when I have @Scheduled method in my bean. Spring also doesn't stops context automatically. Only on CTRL-C.

我想达到类似的效果.我的 main 方法应该只有一行:启动上下文.上下文应该在我的异步服务器启动或停止时启动和停止(已经由 SmartLifecycle 实现),并且应该在请求关闭(CTRL-C,SIGINT等)之前停止.

I want to achieve similar effect. My main method should have only one line: start the context. Context should start and stop my async server when it starts or stops (already achieved by SmartLifecycle) and should not stop until shutdown is requested (CTRL-C, SIGINT etc).

推荐答案

    SpringApplication app = new SpringApplication(Main.class);
    app.setRegisterShutdownHook(false);
    ConfigurableApplicationContext applicationContext= app.run();
    Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
        @Override
        public void run() {
            //do your things
            applicationContext.close();
        }
    }));

这篇关于如何在启动关闭挂钩之前防止Spring应用程序上下文关闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆