In the Spring Boot Document, they said that 'Each SpringApplication will register a shutdown hook with the JVM to ensure that the ApplicationContext is closed gracefully on exit. ' When I click ctrl+c on the shell command, the application can be shutdown gracefully.
Another option to shutdown the Spring Boot application is to close Spring ApplicationContext using SpringApplication . SpringApplication. run(String…) method returns ApplicationContext as a ConfigurableApplicationContext We can use close() method to close ApplicationContext programmatically.
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);
}
}
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);
}
}
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.
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With