如何以编程方式关闭 Spring Boot 应用而不终止VM ?
在其他作品中,与
相反new SpringApplication(Main.class).run(args);
答案 0 :(得分:83)
关闭SpringApplication
基本上意味着关闭基础ApplicationContext
。 SpringApplication#run(String...)
方法会将ApplicationContext
视为ConfigurableApplicationContext
。然后你可以自己close()
。例如,
@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();
}
}
或者,您可以使用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;
}
});
System.exit(exitCode);
}
}
答案 1 :(得分:44)
在Spring启动应用程序中,您可以使用类似这样的内容
<强> 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);
}
}
答案 2 :(得分:27)
这项工作,甚至已完成印刷。
SpringApplication.run(MyApplication.class, args).close();
System.out.println("done");
所以在.close()
run()
说明:
public ConfigurableApplicationContext run(String... args)
运行Spring应用程序,创建并刷新新应用程序 ApplicationContext中。参数:
args
- 应用程序参数(通常从Java main传递 方法)返回: 正在运行的ApplicationContext
和
void close()
关闭此应用程序上下文,释放所有资源 并锁定实现可能包含的内容。这包括摧毁 所有缓存的单例bean。注意:不会在父级上调用close 上下文;父语境有自己独立的生命周期。此方法可以多次调用,没有副作用: 对已经关闭的上下文的后续关闭调用将被忽略。
基本上,它不会关闭父上下文,这就是VM不退出的原因。
答案 3 :(得分:2)
在应用中,您可以使用SpringApplication
。这有一个静态exit()
方法,它有两个参数:ApplicationContext
和ExitCodeGenerator
:
即。你可以声明这个方法:
@Autowired
public void shutDown(ExecutorServiceExitCodeGenerator exitCodeGenerator) {
SpringApplication.exit(applicationContext, exitCodeGenerator);
}
在集成测试中,您可以通过在课程级别添加@DirtiesContext
注释来实现它:
@DirtiesContext(classMode=ClassMode.AFTER_CLASS)
- 在测试类之后,关联的ApplicationContext将被标记为脏。@DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD)
- 在类中的每个测试方法之后,关联的ApplicationContext将被标记为脏。即
@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 {
...
答案 4 :(得分:0)
这将确保SpringBoot应用程序已正确关闭,并且资源已释放到操作系统中,
@Autowired
private ApplicationContext context;
@GetMapping("/shutdown-app")
public void shutdownApp() {
int exitCode = SpringApplication.exit(context, (ExitCodeGenerator) () -> 0);
System.exit(exitCode);
}