简体   繁体   English

Spring Boot-如何为非GUI应用程序注册关闭挂钩

[英]Spring Boot - How to register a shutdown hook for a non-GUI application

I am developing an application which is basically a service that will be run with the command line. 我正在开发一个应用程序,该应用程序基本上是将通过命令行运行的服务。 I do have an option in the config file for it to display a GUI . 我在config文件中确实有一个选项可以显示GUI If the user chooses to have it display the window then I can call my shutdown() method using the WindowClosing event from Swing or a shutdown button. 如果用户选择让它显示窗口,则可以使用Swing的WindowClosing事件或关闭按钮来调用我的shutdown()方法。 However, if the user chooses the no-GUI option, I'm not sure how to ensure this method is called when pressing Control-C in the command prompt. 但是,如果用户选择no-GUI选项,则我不确定在命令提示符下按Control-C时如何确保调用此方法。 My shutdown() method updates some important data in the database and stops threads so I need it to run. 我的shutdown()方法更新了数据库中的一些重要数据并停止了线程,因此我需要它来运行。 I have done some research and tried something like this : 我做了一些研究,并尝试了类似的方法:

public static void main(String args[]) 
{
    //Look and Feel Initialization
    try 
    {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) 
        {
            if ("Nimbus".equals(info.getName())) 
            {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } 
    catch (ClassNotFoundException | IllegalAccessException | InstantiationException | UnsupportedLookAndFeelException ex) 
    {
        logger.error("Error initializing look and feel : " + ex.getMessage());
    } 

    //Application Initialization
    SpringApplication application = new SpringApplication(MDHIS_Service.class);

    application.addListeners((ApplicationListener<ContextClosedEvent>) (ContextClosedEvent e) -> 
    {
        shutdown();
    });

    application.run(args);
}

The problem is that my shutdown() method is far from static. 问题是我的shutdown()方法远非静态。 I do not know how to wire this into the Spring Boot context to have it run this method before stopping. 我不知道如何将其连接到Spring Boot上下文中,以使其在停止之前运行此方法。 I tried the @PreDestroy annotation but it does not run the method as expected. 我尝试了@PreDestroy批注,但未按预期运行该方法。

Any help would be appreciated. 任何帮助,将不胜感激。

Thanks! 谢谢!

See the Runtime API to register a shutdown hook - basically use a Thread to call a method when JVM is terminated (normally or through an interrupt such as CTRL + C). 请参阅运行时API来注册关闭钩子-JVM终止时(通常或通过诸如CTRL + C的中断),基本上使用Thread来调用方法。

In this case it looks like shutdown() would be a static method within the class which defines main() , so something like this: 在这种情况下, shutdown()似乎是定义main()的类中的静态方法,因此如下所示:

public static void main(String args[]) {
    ...
    if (using command line) {
        Runtime.getRuntime().addShutdownHook(new Thread( () -> shutdown() ));
    }
}

Concerning the use of @PreDestroy, this similar question might also help. 关于@PreDestroy的使用,这个类似的问题也可能会有所帮助。

After some more research i ended up implementing the SmartLifecycle interface. 经过更多研究后,我最终实现了SmartLifecycle接口。 My getPhase() method returns Integer.MAX_VALUE; 我的getPhase()方法返回Integer.MAX_VALUE; which means the bean is destroyed first. 这意味着该豆将首先被销毁。 The stop method can then be used to call cleanup code and ensure that any logging / other DB access beans are still alive. 然后,可以使用stop方法来调用清除代码,并确保任何日志记录/其他DB访问bean仍然有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM