2013-01-24 31 views
3

我在Spring框架和我的問題是新低於:使用DefaultMessageListenerContainer問題關機程序

我想實例化DefaultMessageListenerContainer編程,而我使用的代碼是:

DefaultMessageListenerContainer container = new DefaultMessageListenerContainer(); 
container.setConnectionFactory(cf); 
container.setDestination(Queue); 
container.setMessageListener(Consumer); 
container.setReceiveTimeout(-1); 
container.setMaxConcurrentConsumers(15); 
container.setConcurrentConsumers(10); 
container.start(); 

爲什麼我有當我的項目被取消部署時手動關閉DefaultMessageListenerContainer?如果我不手動關閉容器,則消費者會在我的隊列中保持打開狀態。

當我嘗試手動關閉容器(通過調用container.shutdown())時,過程出現問題並且項目無法繼續。 如果我初始化DefaultMessageListenerContainer而不給receiveTimeout關機程序執行正確。 setReceiveTimeout(-1)有問題嗎?

回答

0

你只需要關閉你的聽衆手動,因爲你已經編程方式啓動啦!如果您使用ApplicationContext從xml加載Spring bean,那麼關閉App Context將關閉所有bean。

我發現控制Spring加載bean的最簡單方法是創建一個servlet,實現來自HttpServlet的init()和destroy()方法。 Init()從我的xml文件(即稱爲spring.xml的主文件)加載我的Spring配置,並緩存ApplicationContext對象。然後destory()將在ApplicationContext上調用close()。這將關閉/關閉所有Spring bean(即,您的JMS監聽器將停止)。

你編程方式創建你的聽衆有什麼特別的原因嗎?

+1

謝謝您的回答!我想通過程序生成我的聽衆,因爲我想改變運行時的某些屬性。這些屬性是:併發使用者,每個隊列的最大併發使用者數,接收超時值。通過這種方式,我可以通過JMX提供我的屬性,並用新的值重新啓動監聽器。實例化偵聽器的類實現SmartLifecycle。因此,監聽器在啓動時初始化,並在項目解除部署時銷燬。問題是,當我在setReceiveTimeout方法中設置-1時,當偵聽器嘗試關閉時項目停滯了。 – pbal

+0

查看此類的Spring文檔,我認爲您需要調用stop()來停止偵聽器,如doShutdown()只是似乎取消註冊JMS消費者,這可能會隨着消費者不斷接收(由於timeout = -1)而掛起。 – shuttsy

+0

我試圖在doShutdown()之前阻止聽衆,但問題仍然存在。該項目在執行doShutDown()方法時發生。 – pbal

0

這裏你需要的是能夠停止容器(不關閉它或取消註冊),並且能夠在運行時在需要時啓動備份。只需使用.start()和.stop(),它們是我認爲從AbstractJmsListeningContainer繼承的方法。不要將這些與.doStart(),.shutDown()...混合使用...請參閱spring文檔。

通過使用您的監聽器通過Spring進行連線,您可以隨時從上下文中抓取它,並在其上運行.stop或.start。在Spring自動裝配期間,您可以將屬性autoStartup設置爲false,並且listenerContainer將被初始化,但不會在啓動時進行任何偵聽。

1

receiveTimeout是問題所在。要關閉,容器必須有機會停止監聽隊列。如果你的消費者線程有無限的超時,它將繼續監聽並且不檢查容器是否需要關閉。您的容器將需要關閉receiveTimeout。如果它是-1,它將永遠不會關閉。