2014-10-31 42 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  
    } 

}

相關問題