How can I programmatically shutdown a Spring Boot application without terminating the VM?
如何在不终止VM的情况下以编程方式关闭Spring引导应用程序?
In other works, what is the opposite of
在其他作品中,什么是相反的
new SpringApplication(Main.class).run(args);
4 个解决方案
#1
60
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,
关闭SpringApplication基本上意味着关闭底层的ApplicationContext。SpringApplication#run(String…)方法将ApplicationContext作为一个可配置的ApplicationContext。然后您可以自己关闭它。例如,
@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,
或者,您可以使用静态SpringApplication。退出(ApplicationContext, ExitCodeGenerator…)helper方法为您执行。例如,
@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);
}
}
#2
28
In a spring boot application you can use something like this
在spring引导应用程序中,您可以使用类似的方法。
ShutdownManager.java
ShutdownManager.java
import org.springframework.context.ApplicationContext;
import org.springframework.boot.SpringApplication;
class ShutdownManager{
@Autowired
private ApplicationContext appContext;
public void initiateShutdown(int returnCode){
SpringApplication.exit(appContext, () -> returnCode);
}
}
#3
25
This works, even done is printed.
这个作品,即使完成了也会被打印出来。
SpringApplication.run(MyApplication.class, args).close();
System.out.println("done");
So adding .close()
after run()
所以在run()之后添加。close()
Explanation:
解释:
public ConfigurableApplicationContext run(String... args)
公共ConfigurableApplicationContext运行(字符串…args)
Run the Spring application, creating and refreshing a new ApplicationContext. Parameters:
运行Spring应用程序,创建并刷新一个新的ApplicationContext。参数:
args
- the application arguments (usually passed from a Java main method)args——应用程序参数(通常来自Java main方法)
Returns: a running ApplicationContext
返回: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.void close()关闭这个应用程序上下文,释放实现可能包含的所有资源和锁。这包括销毁所有缓存的单例bean。注意:在父上下文中不调用close;父上下文有它们自己的独立的生命周期。
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 tha parent context, that's why the VM doesn't quit.
所以基本上,它不会关闭父上下文,这就是为什么VM不退出。
#4
1
In the application you can use SpringApplication
. This has a static exit()
method that takes two arguments: the ApplicationContext
and an ExitCodeGenerator
:
在应用程序中,您可以使用SpringApplication。它有一个静态exit()方法,它接受两个参数:ApplicationContext和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注释来实现:
-
@DirtiesContext(classMode=ClassMode.AFTER_CLASS)
- The associated ApplicationContext will be marked as dirty after the test class. - @DirtiesContext(classMode=ClassMode.AFTER_CLASS) -在测试类之后,关联的ApplicationContext将被标记为dirty。
-
@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_EACH_TEST_METHOD)——在类中的每个测试方法之后,关联的ApplicationContext将被标记为dirty。
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 {
...
#1
60
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,
关闭SpringApplication基本上意味着关闭底层的ApplicationContext。SpringApplication#run(String…)方法将ApplicationContext作为一个可配置的ApplicationContext。然后您可以自己关闭它。例如,
@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,
或者,您可以使用静态SpringApplication。退出(ApplicationContext, ExitCodeGenerator…)helper方法为您执行。例如,
@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);
}
}
#2
28
In a spring boot application you can use something like this
在spring引导应用程序中,您可以使用类似的方法。
ShutdownManager.java
ShutdownManager.java
import org.springframework.context.ApplicationContext;
import org.springframework.boot.SpringApplication;
class ShutdownManager{
@Autowired
private ApplicationContext appContext;
public void initiateShutdown(int returnCode){
SpringApplication.exit(appContext, () -> returnCode);
}
}
#3
25
This works, even done is printed.
这个作品,即使完成了也会被打印出来。
SpringApplication.run(MyApplication.class, args).close();
System.out.println("done");
So adding .close()
after run()
所以在run()之后添加。close()
Explanation:
解释:
public ConfigurableApplicationContext run(String... args)
公共ConfigurableApplicationContext运行(字符串…args)
Run the Spring application, creating and refreshing a new ApplicationContext. Parameters:
运行Spring应用程序,创建并刷新一个新的ApplicationContext。参数:
args
- the application arguments (usually passed from a Java main method)args——应用程序参数(通常来自Java main方法)
Returns: a running ApplicationContext
返回: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.void close()关闭这个应用程序上下文,释放实现可能包含的所有资源和锁。这包括销毁所有缓存的单例bean。注意:在父上下文中不调用close;父上下文有它们自己的独立的生命周期。
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 tha parent context, that's why the VM doesn't quit.
所以基本上,它不会关闭父上下文,这就是为什么VM不退出。
#4
1
In the application you can use SpringApplication
. This has a static exit()
method that takes two arguments: the ApplicationContext
and an ExitCodeGenerator
:
在应用程序中,您可以使用SpringApplication。它有一个静态exit()方法,它接受两个参数:ApplicationContext和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注释来实现:
-
@DirtiesContext(classMode=ClassMode.AFTER_CLASS)
- The associated ApplicationContext will be marked as dirty after the test class. - @DirtiesContext(classMode=ClassMode.AFTER_CLASS) -在测试类之后,关联的ApplicationContext将被标记为dirty。
-
@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_EACH_TEST_METHOD)——在类中的每个测试方法之后,关联的ApplicationContext将被标记为dirty。
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 {
...