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

Spring Boot 3.1基于配置列表动态创建JMS监听器Bean并注入

动态创建JMS监听器并实现启停控制

1. 读取配置中的主题列表

首先通过配置绑定类读取yml里的主题列表:

@ConfigurationProperties(prefix = "jms") // 替换为实际配置前缀
public class JmsConsumerProperties {
    private List<String> consumers;

    // getter & setter
    public List<String> getConsumers() {
        return consumers;
    }

    public void setConsumers(List<String> consumers) {
        this.consumers = consumers;
    }
}

在启动类添加注解开启配置绑定:

@SpringBootApplication
@EnableConfigurationProperties(JmsConsumerProperties.class)
public class YourApplication {
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}

2. 编写通用消息处理器

创建统一的消息处理逻辑,适配所有主题:

@Component
public class GenericJmsMessageHandler implements MessageListener {
    @Override
    public void onMessage(Message message) {
        try {
            String topic = message.getJMSDestination().toString();
            String content = ((TextMessage) message).getText();
            // 根据主题做差异化处理或统一逻辑
            System.out.printf("收到来自[%s]的消息:%s%n", topic, content);
        } catch (JMSException e) {
            throw new RuntimeException("消息处理失败", e);
        }
    }
}

3. 动态注册JMS监听器端点

通过JmsListenerConfigurer编程式注册每个主题对应的监听器端点:

@Configuration
@EnableJms
public class DynamicJmsListenerConfig implements JmsListenerConfigurer {

    private final JmsConsumerProperties consumerProps;
    private final GenericJmsMessageHandler messageHandler;

    public DynamicJmsListenerConfig(JmsConsumerProperties consumerProps, GenericJmsMessageHandler messageHandler) {
        this.consumerProps = consumerProps;
        this.messageHandler = messageHandler;
    }

    @Override
    public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {
        List<String> topics = consumerProps.getConsumers();
        if (topics == null || topics.isEmpty()) {
            return;
        }

        for (String topic : topics) {
            SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint();
            // 设置唯一ID,用于后续定位容器
            endpoint.setId("jms-listener-" + topic);
            endpoint.setDestination(topic);
            endpoint.setMessageListener(messageHandler);
            registrar.registerEndpoint(endpoint);
        }
    }
}

4. 实现监听器的挂起/恢复

注入JmsListenerEndpointRegistry,通过端点ID获取容器并控制启停:

@Service
public class JmsListenerManager {

    private final JmsListenerEndpointRegistry endpointRegistry;

    public JmsListenerManager(JmsListenerEndpointRegistry endpointRegistry) {
        this.endpointRegistry = endpointRegistry;
    }

    // 挂起指定主题的监听器
    public void pauseListener(String topic) {
        String listenerId = "jms-listener-" + topic;
        MessageListenerContainer container = endpointRegistry.getListenerContainer(listenerId);
        if (container != null && container.isRunning()) {
            container.pause();
        }
    }

    // 恢复指定主题的监听器
    public void resumeListener(String topic) {
        String listenerId = "jms-listener-" + topic;
        MessageListenerContainer container = endpointRegistry.getListenerContainer(listenerId);
        if (container != null && container.isPaused()) {
            container.resume();
        }
    }
}

配置文件示例

jms:
  consumers:
    - topic_foo
    - topic_bar
    - topic_anything

注意事项

  • 确保JMS连接工厂已正确配置(Spring Boot会自动适配ActiveMQ、RabbitMQ等JMS实现)
  • 端点ID需保证唯一,这里用jms-listener-+主题名的方式避免冲突
  • 若需为不同主题定制处理逻辑,可在GenericJmsMessageHandler中根据主题做分支判断

内容的提问来源于stack exchange,提问作者zamek 42

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 00:20:07