javaswingspring-bootprogram-entry-pointshutdown-hook

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!


Solution

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