Java 以编程方式关闭 Spring Boot 应用程序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22944144/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 19:29:29  来源:igfitidea点击:

Programmatically shut down Spring Boot application

javaspringspring-boot

提问by Axel Fontaine

How can I programmatically shutdowna Spring Bootapplication without terminating the VM?

如何在不终止 VM 的情况下以编程方式关闭Spring Boot应用程序?

In other works, what is the opposite of

在其他作品中,什么是相反的

new SpringApplication(Main.class).run(args);

采纳答案by Sotirios Delimanolis

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

关闭 aSpringApplication基本上意味着关闭底层ApplicationContext. 该SpringApplication#run(String...)方法将其ApplicationContext作为ConfigurableApplicationContext. 然后close()你自己就可以了。

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 staticSpringApplication.exit(ApplicationContext, ExitCodeGenerator...)helper method to do it for you. For example,

或者,您可以使用staticSpringApplication.exit(ApplicationContext, ExitCodeGenerator...)辅助方法为您完成此操作。例如,

@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);
    }
}

回答by ACV

This works, even done is printed.

这行得通,即使完成也被打印出来。

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

So adding .close()after run()

所以添加.close()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

public ConfigurableApplicationContext run(String... args)

运行 Spring 应用程序,创建并刷新一个新的 ApplicationContext。参数:

args- 应用程序参数(通常从 Java 主方法传递)

返回: 一个正在运行的 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.

void close()关闭此应用程序上下文,释放实现可能持有的所有资源和锁。这包括销毁所有缓存的单例 bean。注意:不会在父上下文上调用 close;父上下文有自己独立的生命周期。

可以多次调用此方法而不会产生副作用:对已关闭上下文的后续关闭调用将被忽略。

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

所以基本上,它不会关闭父上下文,这就是 VM 不退出的原因。

回答by snovelli

In a spring boot application you can use something like this

在弹簧启动应用程序中,您可以使用这样的东西

ShutdownManager.java

关机管理器

import org.springframework.context.ApplicationContext;
import org.springframework.boot.SpringApplication;

@Component
class ShutdownManager{

    @Autowired
    private ApplicationContext appContext;

    public void initiateShutdown(int returnCode){
        SpringApplication.exit(appContext, () -> returnCode);
    }
}

回答by magiccrafter

In the applicationyou can use SpringApplication. This has a static exit()method that takes two arguments: the ApplicationContextand an ExitCodeGenerator:

在应用程序中,您可以使用SpringApplication. 这有一个静态exit()方法,它接受两个参数: theApplicationContext和 an ExitCodeGenerator

i.e. you can declare this method:

即你可以声明这个方法:

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

Inside the Integration testsyou can achieved it by adding @DirtiesContextannotation at class level:

在集成测试中,您可以通过@DirtiesContext在类级别添加注释来实现它:

  • @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.
  • @DirtiesContext(classMode=ClassMode.AFTER_CLASS)- 关联的 ApplicationContext 将在测试类之后被标记为脏。
  • @DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD)- 关联的 ApplicationContext 将在类中的每个测试方法之后标记为脏。

i.e.

IE

@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 {
...

回答by Sam

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

这将确保 SpringBoot 应用程序正确关闭并将资源释放回操作系统,

@Autowired
private ApplicationContext context;

@GetMapping("/shutdown-app")
public void shutdownApp() {

    int exitCode = SpringApplication.exit(context, (ExitCodeGenerator) () -> 0);
    System.exit(exitCode);
}