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
Programmatically shut down Spring Boot application
提问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 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.
关闭 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 static
SpringApplication.exit(ApplicationContext, ExitCodeGenerator...)
helper method to do it for you. For example,
或者,您可以使用static
SpringApplication.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 ApplicationContext
and 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 @DirtiesContext
annotation 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);
}