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"); } }); } 

但是当应用程序关闭时,不会调用此已注册的侦听器。

http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-application-exit

每个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 } }