如何为Spring JMS生产者配置独立的MessageConverter
解决JmsTemplate指定自定义MessageConverter发送消息的问题
方案1:创建专用的JmsTemplate Bean
既然你已经实现了SomeReplyConverter,可以单独创建一个配置了该转换器的JmsTemplate Bean,专门用于发送SomeReply类型的消息:
@Configuration public class JmsConfig { // 监听容器工厂,配置接收请求用的SomeRequestConverter @Bean public JmsListenerContainerFactory<?> jmsListenerContainerFactory(ConnectionFactory connectionFactory, SomeRequestConverter requestConverter) { DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); factory.setConnectionFactory(connectionFactory); factory.setMessageConverter(requestConverter); return factory; } // 专用发送回复的JmsTemplate,绑定SomeReplyConverter @Bean(name = "replyJmsTemplate") public JmsTemplate replyJmsTemplate(ConnectionFactory connectionFactory, SomeReplyConverter replyConverter) { JmsTemplate template = new JmsTemplate(connectionFactory); template.setMessageConverter(replyConverter); return template; } }
在监听类中注入这个专用模板即可:
@JmsListener(destination = "request-queue") public void onMessage(SomeRequest someRequest, @Qualifier("replyJmsTemplate") JmsTemplate replyJmsTemplate) { var myObject = MyObject.builder() .data(someRequest.data) .build(); var someReply = SomeReply.builder() .prop(myObject.getData()) .build(); replyJmsTemplate.convertAndSend("reply-queue", someReply); }
方案2:调用convertAndSend时直接传入指定转换器
如果不想额外创建JmsTemplate Bean,可以直接使用convertAndSend的重载方法,在调用时传入目标转换器:
先确保SomeReplyConverter被Spring托管:
@Component public class SomeReplyConverter implements MessageConverter { // 实现你的消息转换逻辑 }
然后在监听方法中注入该转换器并使用:
@JmsListener(destination = "request-queue") public void onMessage(SomeRequest someRequest, JmsTemplate jmsTemplate, SomeReplyConverter replyConverter) { var myObject = MyObject.builder() .data(someRequest.data) .build(); var someReply = SomeReply.builder() .prop(myObject.getData()) .build(); // 传入指定转换器执行发送 jmsTemplate.convertAndSend("reply-queue", someReply, replyConverter); }
方案3:使用CompositeMessageConverter(多类型适配场景)
如果系统存在多种消息类型需要不同转换器处理,可以用CompositeMessageConverter组合多个转换器,它会按顺序尝试匹配可用的转换器:
@Bean public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory, SomeRequestConverter requestConverter, SomeReplyConverter replyConverter) { JmsTemplate template = new JmsTemplate(connectionFactory); CompositeMessageConverter compositeConverter = new CompositeMessageConverter(Arrays.asList(requestConverter, replyConverter)); template.setMessageConverter(compositeConverter); return template; }
注意:每个转换器的fromMessage和toMessage方法需要先判断消息类型是否属于自身处理范围,不属于则返回null,Composite会自动尝试下一个转换器。
内容的提问来源于stack exchange,提问作者magos
相关产品推荐
相关产品推荐

