You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置JmsListenerEndpointRegistry Bean并控制JMS监听器启停

非Spring Boot环境下JmsListenerEndpointRegistry配置与JMS消费者启停方案

核心问题在于你只声明了JmsListenerEndpointRegistry Bean但未关联实际的消息监听容器,导致无法通过它调用启停方法。以下是完整的配置与实现步骤:

1. 配置JMS监听容器工厂

先创建JmsListenerContainerFactory,用于生成消息监听容器,可根据需求选择DefaultJmsListenerContainerFactory(支持动态调整并发、事务)或SimpleJmsListenerContainerFactory:

@Bean
public JmsListenerContainerFactory<?> jmsListenerContainerFactory(ConnectionFactory connectionFactory) {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory);
    // 配置并发数、事务等自定义属性
    factory.setConcurrency("1-3");
    factory.setSessionTransacted(true);
    return factory;
}

2. 配置JmsListenerEndpointRegistry并注册监听端点

手动创建MethodJmsListenerEndpoint(对应方法级的消息监听),并将其注册到JmsListenerEndpointRegistry,确保registry持有容器引用:

@Bean
public JmsListenerEndpointRegistry jmsListenerEndpointRegistry() {
    return new JmsListenerEndpointRegistry();
}

@Bean
public MethodJmsListenerEndpoint myJmsConsumerEndpoint(JmsListenerContainerFactory<?> containerFactory, MyMessageListener messageListener) {
    MethodJmsListenerEndpoint endpoint = new MethodJmsListenerEndpoint();
    // 设置唯一ID,用于后续定位容器
    endpoint.setId("myJmsConsumer");
    // 指定监听的JMS目的地(队列/主题)
    endpoint.setDestination("order-queue");
    // 绑定自定义消息监听器
    endpoint.setMessageListener(messageListener);
    endpoint.setContainerFactory(containerFactory);
    
    // 将端点注册到registry,第三个参数false表示不自动启动容器(按需启停)
    jmsListenerEndpointRegistry().registerListenerContainer(endpoint, containerFactory, false);
    return endpoint;
}

3. 自定义消息监听器

实现具体的消息处理逻辑:

@Component
public class MyMessageListener {
    public void onMessage(Message message) throws JMSException {
        TextMessage textMessage = (TextMessage) message;
        System.out.println("处理消息:" + textMessage.getText());
        // 业务逻辑处理
    }
}

4. 实现消费者启停控制

通过注入的JmsListenerEndpointRegistry获取容器,调用start()/stop()方法实现按需启停:

@Component
public class JmsConsumerController {
    private final JmsListenerEndpointRegistry registry;

    public JmsConsumerController(JmsListenerEndpointRegistry registry) {
        this.registry = registry;
    }

    // 根据标志启停消费者
    public void controlConsumer(boolean startConsumer) {
        MessageListenerContainer container = registry.getListenerContainer("myJmsConsumer");
        if (container == null) {
            throw new IllegalArgumentException("未找到ID为myJmsConsumer的消息容器");
        }
        
        if (startConsumer && !container.isRunning()) {
            container.start();
            System.out.println("JMS消费者已启动");
        } else if (!startConsumer && container.isRunning()) {
            container.stop();
            System.out.println("JMS消费者已停止");
        }
    }
}

关键注意点

  • 必须为每个监听端点设置唯一ID,否则无法通过registry准确获取对应的容器。
  • 注册端点时第三个参数设为false,避免容器自动启动,实现按需启停。
  • 启停前判断容器运行状态,避免重复操作引发异常。

内容的提问来源于stack exchange,提问作者Vishal Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 22:35:21