如何在启动关闭挂钩之前防止Spring应用程序上下文关闭 [英] How to prevent Spring app context shutdown until shutdown hook is fired
问题描述
我有一个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屋!