2013-05-04 13 views
8

Ho un bean Spring definita beans.xml come segue:metodo @PreDestroy di un bean Spring singoletto non chiamato

<context:annotation-config /> 
[...] 
<bean id="myBackend" class="mycompany.BackendBean" scope="singleton" /> 

All'interno del fagiolo sono 2 metodi, che devono essere eseguiti all'inizio e prima della terminazione della applicazione web:

public class BackendBean implements IBackend { 
    private static final Logger LOGGER = LoggerFactory 
      .getLogger(BackendBean.class); 

    @PostConstruct 
    public void init() 
    { 
     LOGGER.debug("init"); 
    } 

    @PreDestroy 
    public void destroy() 
    { 
     LOGGER.debug("destroy"); 
    } 
} 

Quando eseguo il server (mvn jetty:run), posso vedere l'output del metodo init nella console, da cui concludo che il metodo init viene eseguito.

Quando si preme Ctrl-C e il Jetty inizia a chiudere, non vedo l'output del metodo destroy.

Cosa è necessario modificare per l'esecuzione del metodo destroy quando l'applicazione viene terminata?

+0

Hai intenzione di eseguire l'applicazione sul pontile? O hai bisogno di eseguirlo in più contenitori? – ssedano

+0

Sto usando il jetty solo per test rapidi. In produzione, sto usando Apache Tomcat 7. –

risposta

8

Per la Primavera per chiamare @PreDestroy metodo di callback quando l'applicazione si chiude, è necessario aggiungere un gancio di arresto e chiudere il contesto dell'applicazione in. Si potrebbe agganciarlo JVM utilizzando Runtime.getRuntime().addShutdownHook(Thread) o al Jetty se fornisce un tale API . Ecco come lo faresti con il gancio di arresto JVM:

final ApplicationContext appContext = ... // create your application context 
         // using one of the various application context classes 
Runtime.getRuntime().addShutdownHook(new Thread() { 
    public void run() { 
     appContext.close(); 
    }}); 
+11

C'è 'appContext.registerShutdownHook()' per quello. – Vitaly

+0

Grazie. Dove (in quale metodo) dovrei inserire la registrazione del gancio di chiusura? –

+1

@DmitriPisarenko Il posto migliore sarebbe dove inizializzate il vostro contesto applicativo di primavera. –

0

Non so perché si desidera che Spring si occupi di questo. A meno che non abbia frainteso la tua domanda, puoi andare con il ciclo di vita delle applicazioni dei contenitori.

provare a scrivere una sostituzione LifeCycle (jetty) e LifeCycleListener (tomcat) e in LifeCyleonStart e onStop. E lavorare una soluzione simile per LifeCycleListener in Tomcat quando si verifica l'appropriato event.

+4

Se lo fai, induci una dipendenza tra il codice di arresto e il contenitore. Probabilmente è meglio evitarlo e mantenere una singola dipendenza da Spring, che è già presente (o ancora meglio rimuovere qualsiasi dipendenza da Spring e usare le annotazioni javax.inject). –

Problemi correlati