如果我在RabbitTemplate上直接设置它们,为什么Spring需要在Converter和ClassMapper上使用@Bean?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如果我在RabbitTemplate上直接设置它们,为什么Spring需要在Converter和ClassMapper上使用@Bean?相关的知识,希望对你有一定的参考价值。
我想了解为什么我需要用getMessageConverter
标记classMapper
和@Bean
方法,甚至直接在我的自定义RabbiteTemplate中设置它们。
没有@Bean
并将它们传递给private
,消息中没有正确包含TypeId
。
所以,使用@Bean和public方法,我在消息上有正确的标题:
headers: __TypeId__: OrderProducer
没有它们,消息包含不正确的TypeId:
headers: __TypeId__: com.projet.order.message.OrderProducer
没有classMapper的默认行为是什么。
看代码:
@Bean(name = "sendCommandOrderCreate")
public RabbitTemplate sendCommandOrderCreate() {
RabbitTemplate rabbitTemplate = createRabbitTemplate(getMessageConverter());
rabbitTemplate.setExchange("order.exchange");
rabbitTemplate.setRoutingKey("order.cmd.create");
return rabbitTemplate;
}
private RabbitTemplate createRabbitTemplate(final MessageConverter messageConverter) {
final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(messageConverter);
return rabbitTemplate;
}
@Bean
public Jackson2JsonMessageConverter getMessageConverter() {
Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();
jackson2JsonMessageConverter.setClassMapper(classMapper());
return jackson2JsonMessageConverter;
}
@Bean
public DefaultClassMapper classMapper() {
DefaultClassMapper classMapper = new DefaultClassMapper();
Map<String, Class<?>> idClassMapping = new HashMap<>();
idClassMapping.put(OrderProducer.class.getSimpleName(), OrderProducer.class);
idClassMapping.put(OrderConsumer.class.getSimpleName(), OrderConsumer.class);
classMapper.setIdClassMapping(idClassMapping);
return classMapper;
}
我是如何在服务中注入bean的:
public OrderService(@Qualifier("sendCommandOrderCreate") RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
}
我发现了这个问题。我决定使用另一个Mapper:DefaultJackson2JavaTypeMapper
。
private DefaultJackson2JavaTypeMapper classMapper() {
DefaultJackson2JavaTypeMapper classMapper = new DefaultJackson2JavaTypeMapper();
Map<String, Class<?>> idClassMapping = new HashMap<>();
idClassMapping.put(OrderProducer.class.getSimpleName(), OrderProducer.class);
idClassMapping.put(OrderConsumer.class.getSimpleName(), OrderConsumer.class);
classMapper.setIdClassMapping(idClassMapping);
return classMapper;
}
调试代码并查找ClassMapper的不同实现后,我可以找到这个映射器。 DefaultClassMapper
无法提供我期待的行为,我无法解释为什么用@Bean
声明它可能会改变他的行为(可能是Spring上的一个bug)。
以上是关于如果我在RabbitTemplate上直接设置它们,为什么Spring需要在Converter和ClassMapper上使用@Bean?的主要内容,如果未能解决你的问题,请参考以下文章
Spring RabbitTemplate - 如何在发送时自动创建队列
RabbitTemplate 连接到 RabbitMQ:获取 - NOT_FOUND - 无队列
如何使用 RabbitTemplate 模仿 SimpMessagingTemplate.convertAndSendToUser?