Spring Boot关闭钩子
如何注册/添加一个自定义关闭例程,该例程将在我的Spring Boot应用程序关闭时触发?
场景:我将Spring Boot应用程序部署到Jetty servlet容器(即没有嵌入式Jetty)。 我的应用程序使用Logback进行日志记录,我想使用Logback的MBean JMX配置程序在运行时更改日志记录级别。 其文档指出,为了避免内存泄漏,在关闭时必须调用特定的LoggerContext关闭方法 。
听取Spring Boot关闭事件的好方法是什么?
我努力了:
public static void main(String[] args) throws Exception { ConfigurableApplicationContext cac = SpringApplication.run(Example.class, args); cac.addApplicationListener(new ApplicationListener() { @Override public void onApplicationEvent(ContextClosedEvent event) { logger.info("Do something"); } }); }
但是当应用程序关闭时,不会调用此已注册的侦听器。
每个SpringApplication都会向JVM注册一个关闭钩子,以确保在退出时正常关闭ApplicationContext。 可以使用所有标准的Spring生命周期回调(例如DisposableBean接口或@PreDestroy注释)。
此外,如果bean希望在应用程序结束时返回特定的退出代码,则bean可以实现org.springframework.boot.ExitCodeGenerator接口。
您的监听器注册太晚(在上下文已关闭之前永远不会到达该行)。 它应该足以成为一个@Bean
。
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletListenerRegistrationBean; import org.springframework.boot.web.support.SpringBootServletInitializer; import org.springframework.context.annotation.Bean; @SpringBootApplication @EnableAutoConfiguration public class Application extends SpringBootServletInitializer { public static void main( String[] args) { SpringApplication.run(Application.class, args); } @NotNull @Bean ServletListenerRegistrationBean myServletListener() { ServletListenerRegistrationBean srb = new ServletListenerRegistrationBean<>(); srb.setListener(new ExampleServletContextListener()); return srb; } } import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class ExampleServletContextListener implements ServletContextListener { @Override public void contextInitialized( ServletContextEvent sce) { // Context Initialised } @Override public void contextDestroyed( ServletContextEvent sce) { // Here - what you want to do that context shutdown } }