0

我有一个场景,我需要停止 spring 的 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>
4

3 回答 3

4

DefaultMessageListenerContainer是一个生命周期 bean,因此它公开了一个start和一个stop方法,您可以分别使用它来启动和停止侦听器。

您可以自己构建一个服务,收集上下文中的所有已知实例,然后您可以遍历这些实例以停止容器,例如

@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,那么您的设计肯定有问题
于 2014-07-29T13:52:26.077 回答
2

DefaultMessageListenerContainer 上的 stop 方法不起作用,但 shutdown 方法工作得很好。

 for(DefaultMessageListenerContainer defaultCont:containers){
         defaultCont.shutdown();
      }
于 2015-06-10T10:39:51.063 回答
0

注入一组 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();
            }
        });
    }

}
于 2018-03-28T22:11:43.200 回答