2013-05-04 89 views
8

我在beans.xml定義一個Spring bean如下:@PreDestroy方法不叫

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

豆內部是2種方法,必須在開始和終止之前執行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"); 
    } 
} 

當運行服務器(mvn jetty:run),I可以看到init方法的在控制檯的輸出,從中我結束時所執行的方法init

當我按Ctrl-C和Jetty開始關閉時,我看不到destroy方法的輸出。

當應用程序終止時,爲了執行destroy方法,應該更改什麼?

+0

你打算在jetty上運行應用程序嗎?或者你需要在更多的容器中運行它? – ssedano 2013-05-04 10:30:03

+0

我只使用Jetty進行快速測試。在生產中,我使用的是Apache Tomcat 7. – 2013-05-04 10:32:36

回答

8

春天調用@PreDestroy回調方法,當你的應用程序關閉,您必須添加一個關閉掛鉤,並關閉應用程序上下文它,你可以使用Runtime.getRuntime().addShutdownHook(Thread)鉤連接到JVM或碼頭,如果它提供了這樣的API 。下面是你如何使用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

有'appContext.registerShutdownHook()'。 – Vitaly 2013-05-04 11:00:18

+0

謝謝。我應該在哪裏(在哪個方法中)關閉掛鉤註冊? – 2013-05-04 12:42:15

+1

@DmitriPisarenko最好的地方是你初始化你的spring應用程序上下文的地方。 – 2013-05-04 14:00:53

0

我不知道你爲什麼要Spring來照顧這個。除非我誤解了你的問題,否則你可以使用容器應用程序生命週期。

嘗試在LifeCyleonStartonStopLifeCycle (jetty)LifeCycleListener (tomcat)和覆蓋。在適當的event發生時,爲tomcat中的LifeCycleListener工作類似的解決方案。

+4

如果這樣做,您會在關閉代碼和容器之間產生依賴關係。避免它可能會更好,並且保留了Spring的一個依賴關係(已經存在)(或者更好地移除對Spring的依賴關係並使用javax.inject註釋)。 – 2013-11-04 17:25:45