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

Spring 4.x中为@JmsListener设置NON_PERSISTENT投递模式

针对Spring 4.x @JmsListener设置回复消息投递模式的优化方案

针对你的Spring 4.x + IBM MQ场景,我整理了几个比全局修改MessagingMessageListenerAdapter更灵活的方案,能精准为单个或部分@JmsListener方法设置回复的NON_PERSISTENT投递模式:

方案一:直接在回复消息上设置投递模式(最简便)

如果你的@JmsListener方法是直接返回Message对象,那可以在构造回复消息时直接指定投递模式,Spring会自动沿用这个属性发送回复:

@JmsListener(destination = "your.input.queue")
public Message handleIncomingMessage(Message receivedMsg, Session session) throws JMSException {
    // 构造回复消息
    TextMessage replyMsg = session.createTextMessage("处理完成的回复内容");
    // 直接设置投递模式为NON_PERSISTENT
    replyMsg.setJMSDeliveryMode(DeliveryMode.NON_PERSISTENT);
    return replyMsg;
}

这个方式完全不需要额外配置,只针对当前方法生效,不会影响其他监听方法,是最简单直接的解决方案。

方案二:用自定义JmsTemplate手动发送回复

如果你的方法是返回普通对象(比如String),可以手动创建一个配置好投递模式的JmsTemplate来发送回复,完全控制发送逻辑:

@Autowired
private ConnectionFactory connectionFactory;

@JmsListener(destination = "your.input.queue")
public void handleMessage(Message receivedMsg) throws JMSException {
    // 初始化JmsTemplate并配置投递模式
    JmsTemplate replyTemplate = new JmsTemplate(connectionFactory);
    replyTemplate.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
    
    // 从收到的消息中获取回复目的地
    Destination replyDest = receivedMsg.getJMSReplyTo();
    // 发送回复
    replyTemplate.send(replyDest, session -> session.createTextMessage("自定义模板的回复内容"));
}

这种方式适合需要对回复做更多自定义配置的场景,比如设置优先级、过期时间等,同样只作用于当前方法。

方案三:自定义注解+适配器实现局部配置

如果多个监听方法需要不同的投递模式,你可以通过自定义注解+扩展MessagingMessageListenerAdapter来实现灵活配置:

1. 定义自定义注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface JmsReplyDeliveryMode {
    int value() default DeliveryMode.PERSISTENT;
}

2. 扩展消息监听适配器

public class AnnotationBasedMessageListenerAdapter extends MessagingMessageListenerAdapter {

    @Override
    protected void postProcessProducer(Session session, MessageProducer producer) throws JMSException {
        // 获取当前处理的监听方法
        Method targetMethod = getHandlerMethod().getMethod();
        JmsReplyDeliveryMode deliveryModeAnn = targetMethod.getAnnotation(JmsReplyDeliveryMode.class);
        
        if (deliveryModeAnn != null) {
            // 根据注解设置投递模式
            producer.setDeliveryMode(deliveryModeAnn.value());
        } else {
            // 没有注解时用默认逻辑(比如IBM MQ的PERSISTENT)
            super.postProcessProducer(session, producer);
        }
    }
}

3. 配置JmsListenerContainerFactory

@Bean
public JmsListenerContainerFactory<?> jmsListenerContainerFactory(ConnectionFactory connectionFactory) {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory);
    // 替换为自定义的适配器
    factory.setMessageListenerAdapter(new AnnotationBasedMessageListenerAdapter());
    return factory;
}

4. 在需要的监听方法上使用注解

@JmsListener(destination = "queue.need.non.persistent")
@JmsReplyDeliveryMode(DeliveryMode.NON_PERSISTENT)
public String handleNonPersistentReply(String message) {
    return "非持久化回复";
}

// 其他方法不添加注解则保持默认的PERSISTENT
@JmsListener(destination = "queue.default.persistent")
public String handlePersistentReply(String message) {
    return "持久化回复";
}

这个方案兼顾了@JmsListener的便捷性和配置灵活性,适合多方法需要不同投递模式的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:45:04