簡體   English   中英

停止Spring JMS消息監聽器

[英]Stop a spring jms message listener

我有一種情況,需要停止彈簧的DefaultMessageListenerContainer,然后再重新啟動。 我有10個不同的DefaultMessageListenerContainer,它們偵聽10個不同的隊列。 所有10個不同的容器都在調用同一消息偵聽器類的相同方法。 現在,我想根據onMessage方法中獲得的異常,停止特定隊列的messagelistenercontainer。 請建議我如何實現上述方案。

下面是我的監聽器配置

<bean id="msglistenerForAuditError" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="jmsFactory"/>
        <property name="sessionTransacted" value="true"/>
        <property name="destinationName" value="test.audit.error2"/>
        <property name="messageListener" ref="auditerrorListener" />
    </bean>

    <bean id="msglistenerForAuditEvent" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="jmsFactory"/>
        <property name="sessionTransacted" value="true"/>
        <property name="destinationName" value="test.audit.event2"/>
        <property name="messageListener" ref="auditerrorListener" />
    </bean>

DefaultMessageListenerContainer是一個生命周期bean,因此它公開了可以分別用來啟動和停止偵聽器的startstop方法。

您可以自己構建一個服務,以收集上下文中的所有已知實例,然后可以遍歷這些實例以停止容器,例如

@Service
public class MyService {

    private final Collection<DefaultMessageListenerContainer> containers;

    @Autowired
    public MyService(Collection<DefaultMessageListenerContainer> containers) {
        this.containers = containers;
    }

    public void stopAll() {
        // iterate over the collection and call "stop()" on each item
    }
}

話雖如此:

  1. 您不應在消息偵聽器中調用此服務,因為在線程處理消息時嘗試停止容器會產生怪異的副作用
  2. 整個用例對我來說可疑。 您的消息偵聽器應該具有彈性,更重要的是,它們應該彼此獨立。 如果由於偵聽器B拋出異常而停止了偵聽器A,則在您的設計中肯定存在錯誤

DefaultMessageListenerContainer上的stop方法無法正常工作,但shutdown方法可以正常工作。

 for(DefaultMessageListenerContainer defaultCont:containers){
         defaultCont.shutdown();
      }

注入DefaultMessageListenerContainer的集合對我不起作用,我使用Spring Boot 1.4.x和Spring 4.3.x

這是我解決的方法:

package org.example.queue;

import org.springframework.jms.config.JmsListenerEndpointRegistry;
//import other stuffs

@Component
public class QueueManager {


   @Autowired
   JmsListenerEndpointRegistry endpointRegistry;


    public void shutdown() {
        endpointRegistry.getListenerContainers().forEach((container) -> {
            if (container.isRunning()) {
                log.debug("Shutting down listener: " + container.getClass().getName());
                container.stop();
            }
        });
    }

    public void start() {
        endpointRegistry.getListenerContainers().forEach((container) -> {
            if (!container.isRunning()) {
                log.debug("Starting listener: " + container.getClass().getName());
                container.start();
            }
        });
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM