2014-10-31 907 views
26

如何注册/添加一个自定义关闭例程,当我的Spring Boot应用程序关闭时应该触发该例程?Spring Boot关闭钩子

场景:我将Spring Boot应用程序部署到Jetty servlet容器(即没有嵌入式Jetty)。我的应用程序使用Logback进行日志记录,并且我想在运行时使用Logback的MBean JMX配置程序更改日志记录级别。 Its documentation states that to avoid memory leaks, on shutdown a specific LoggerContext shutdown method has to be called

有什么好的方法来收听Spring Boot关机事件?

我曾尝试:

public static void main(String[] args) throws Exception { 
    ConfigurableApplicationContext cac = SpringApplication.run(Example.class, args); 

    cac.addApplicationListener(new ApplicationListener<ContextClosedEvent>() { 

     @Override 
     public void onApplicationEvent(ContextClosedEvent event) { 
      logger.info("Do something"); 
     } 
    }); 
} 

但是当应用程序关闭该注册的监听器不会被调用。

+0

您正在注册的侦听器创建的上下文后,基本上使之无用。如果你想让它参与进来,你需要将它注册为应用程序上下文中的bean,就像其他bean一样。 – 2014-11-02 17:07:42

+0

你是否设法解决了这个问题? – pvgoddijn 2016-05-18 15:25:24

回答

19

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

每个SpringApplication将注册与JVM关闭挂钩,以确保ApplicationContext需要在退出正常关闭。可以使用所有标准的Spring生命周期回调(如DisposableBean接口或@PreDestroy注释)。

另外,如果bean在应用程序结束时希望返回特定的退出代码,则它们可以实现org.springframework.boot.ExitCodeGenerator接口。

+0

我已经更新了我的问题,以显示我目前不成功的工作 – Abdull 2014-10-31 16:24:56

6

你的监听者注册太晚了(直到上下文已经关闭,该行才会被触发)。它应该足以使其成为@Bean

1
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<ServletContextListener> myServletListener() { 
     ServletListenerRegistrationBean<ServletContextListener> 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  
    } 

}

相关问题