2014-10-31 17 views
26

Come posso registrare/aggiungere una routine di spegnimento personalizzata che deve essere attivata quando la mia applicazione Spring Boot si spegne?Spring Spring shutdown hook

Scenario: distribuisco la mia applicazione Spring Boot su un contenitore di servlet Jetty (ad esempio, nessun Jetty incorporato). La mia applicazione utilizza Logback per la registrazione e desidero modificare i livelli di registrazione durante il runtime utilizzando il configuratore JMX MBean di Logback. Its documentation states that to avoid memory leaks, on shutdown a specific LoggerContext shutdown method has to be called.

Quali sono i modi migliori per ascoltare gli eventi di chiusura di Spring Boot?

ho provato:

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

ma questo ascoltatore registrato non viene chiamato quando l'applicazione viene chiusa.

+0

si sta registrando l'ascoltatore dopo la creazione del contesto, in fondo rendendolo inutilizzabile. Se vuoi che partecipi è necessario registrarlo come bean nel contesto dell'applicazione come qualsiasi altro bean. –

+0

sei riuscito a risolvere questo problema? – pvgoddijn

risposta

19

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

Ogni SpringApplication registrerà un gancio di arresto con la JVM per garantire che l'ApplicationContext è chiuso con grazia all'uscita. È possibile utilizzare tutti i callback del ciclo di vita standard di Spring (come l'interfaccia DisposableBean o l'annotazione @PreDestroy).

Inoltre, i bean possono implementare l'interfaccia org.springframework.boot.ExitCodeGenerator se desiderano restituire un codice di uscita specifico al termine dell'applicazione.

+0

Ho aggiornato la mia domanda per mostrare il mio attuale sforzo infruttuoso – Abdull

6

L'ascoltatore è registrato troppo tardi (tale linea non sarà mai raggiunta finché il contesto non è già chiuso). Dovrebbe essere sufficiente a renderlo un @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  
    } 

}

Problemi correlati