简体   繁体   中英

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 . 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. 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. My shutdown() method updates some important data in the database and stops threads so I need it to run. 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. I do not know how to wire this into the Spring Boot context to have it run this method before stopping. I tried the @PreDestroy annotation but it does not run the method as expected.

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

In this case it looks like shutdown() would be a static method within the class which defines main() , so something like this:

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.

After some more research i ended up implementing the SmartLifecycle interface. My getPhase() method returns 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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