Programmatically shut down Spring Boot application

前端 未结 5 1218
误落风尘
误落风尘 2020-11-27 13:52

How can I programmatically shutdown a Spring Boot application without terminating the VM?

In other works, what is

相关标签:
5条回答
  • 2020-11-27 14:09

    This will make sure that the SpringBoot application is closed properly and the resources are released back to the operating system,

    @Autowired
    private ApplicationContext context;
    
    @GetMapping("/shutdown-app")
    public void shutdownApp() {
    
        int exitCode = SpringApplication.exit(context, (ExitCodeGenerator) () -> 0);
        System.exit(exitCode);
    }
    
    0 讨论(0)
  • 2020-11-27 14:17

    In the application you can use SpringApplication. This has a static exit() method that takes two arguments: the ApplicationContext and an ExitCodeGenerator:

    i.e. you can declare this method:

    @Autowired
    public void shutDown(ExecutorServiceExitCodeGenerator exitCodeGenerator) {
        SpringApplication.exit(applicationContext, exitCodeGenerator);
    }
    

    Inside the Integration tests you can achieved it by adding @DirtiesContext annotation at class level:

    • @DirtiesContext(classMode=ClassMode.AFTER_CLASS) - The associated ApplicationContext will be marked as dirty after the test class.
    • @DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD) - The associated ApplicationContext will be marked as dirty after each test method in the class.

    i.e.

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes = {Application.class},
        webEnvironment= SpringBootTest.WebEnvironment.DEFINED_PORT, properties = {"server.port:0"})
    @DirtiesContext(classMode= DirtiesContext.ClassMode.AFTER_CLASS)
    public class ApplicationIT {
    ...
    
    0 讨论(0)
  • 2020-11-27 14:26

    This works, even done is printed.

      SpringApplication.run(MyApplication.class, args).close();
      System.out.println("done");
    

    So adding .close() after run()

    Explanation:

    public ConfigurableApplicationContext run(String... args)

    Run the Spring application, creating and refreshing a new ApplicationContext. Parameters:

    args - the application arguments (usually passed from a Java main method)

    Returns: a running ApplicationContext

    and:

    void close() Close this application context, releasing all resources and locks that the implementation might hold. This includes destroying all cached singleton beans. Note: Does not invoke close on a parent context; parent contexts have their own, independent lifecycle.

    This method can be called multiple times without side effects: Subsequent close calls on an already closed context will be ignored.

    So basically, it will not close the parent context, that's why the VM doesn't quit.

    0 讨论(0)
  • 2020-11-27 14:33

    Closing a SpringApplication basically means closing the underlying ApplicationContext. The SpringApplication#run(String...) method gives you that ApplicationContext as a ConfigurableApplicationContext. You can then close() it yourself.

    For example,

    @SpringBootApplication
    public class Example {
        public static void main(String[] args) {
            ConfigurableApplicationContext ctx = SpringApplication.run(Example.class, args);
            // ...determine it's time to shut down...
            ctx.close();
        }
    }
    

    Alternatively, you can use the static SpringApplication.exit(ApplicationContext, ExitCodeGenerator...) helper method to do it for you. For example,

    @SpringBootApplication
    public class Example {
        public static void main(String[] args) {
            ConfigurableApplicationContext ctx = SpringApplication.run(Example.class, args);
            // ...determine it's time to stop...
            int exitCode = SpringApplication.exit(ctx, new ExitCodeGenerator() {
                @Override
                public int getExitCode() {
                    // no errors
                    return 0;
                }
            });
    
            // or shortened to
            // int exitCode = SpringApplication.exit(ctx, () -> 0);
    
            System.exit(exitCode);
        }
    }
    
    0 讨论(0)
  • 2020-11-27 14:34

    The simplest way would be to inject the following object where you need to initiate the shutdown

    ShutdownManager.java

    import org.springframework.context.ApplicationContext;
    import org.springframework.boot.SpringApplication;
    
    @Component
    class ShutdownManager {
    
        @Autowired
        private ApplicationContext appContext;
    
        /*
         * Invoke with `0` to indicate no error or different code to indicate
         * abnormal exit. es: shutdownManager.initiateShutdown(0);
         **/
        public void initiateShutdown(int returnCode){
            SpringApplication.exit(appContext, () -> returnCode);
        }
    }
    
    0 讨论(0)
提交回复
热议问题