2013-05-04 15 views
8

Mam fasoli Wiosna zdefiniowany w beans.xml następująco:metoda @PreDestroy z fasoli Wiosna singleton nie nazywa

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

Wewnątrz fasoli są 2 metody, które muszą być wykonane na początku i przed zakończeniem aplikacja internetowa:

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

Kiedy uruchomić serwer (mvn jetty:run), widzę wyjście metody init w konsoli, z której wnioskuję, że metoda init jest wykonywany.

Po naciśnięciu Ctrl-C i Jetty zaczyna się wyłączać, nie widzę wyjścia z metody destroy.

Co należy zmienić, aby metoda destroy została wykonana po zakończeniu aplikacji?

+0

Czy planujesz uruchomić aplikację na pomoście? Lub musisz uruchomić go w większej ilości pojemników? – ssedano

+0

Używam Jetty tylko do szybkich testów. W produkcji używam Apache Tomcat 7. –

Odpowiedz

8

Aby wywołać metodę zwrotną @PreDestroy po zamknięciu aplikacji, należy dodać hak zamykający i zamknąć kontekst aplikacji. Możesz dołączyć hak do JVM przy użyciu Runtime.getRuntime().addShutdownHook(Thread) lub do Jetty, jeśli zapewnia takie API . Oto, jak to zrobić z hakiem wyłączającym 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

Istnieje 'appContext.registerShutdownHook()' do tego. – Vitaly

+0

Dzięki. Gdzie (w jakiej metodzie) powinienem umieścić rejestrację haka zamknięcia? –

+1

@DmitriPisarenko Najlepszym miejscem będzie miejsce, w którym zainicjujesz kontekst aplikacji wiosennej. –

0

Nie wiem, dlaczego chcesz Spring zająć się tym. O ile nie zinterpretuję twojego pytania, możesz przejść do cyklu życiowego pojemników.

Spróbuj napisać LifeCycle (jetty) i LifeCycleListener (tomcat) i zastąpić w LifeCyleonStart i onStop. I pracuj nad podobnym rozwiązaniem dla LifeCycleListener w tomcat, gdy nastąpi odpowiednia event.

+4

Jeśli to zrobisz, wywołasz zależność między kodem zamknięcia a kontenerem. Prawdopodobnie lepiej jest tego uniknąć i zachować jedną zależność do Spring, która już istnieje (lub jeszcze lepiej usunąć wszelkie zależności od Springa i używać adnotacji javax.inject). –

Powiązane problemy