我尝试使用与RabbitMQ的Spring集成,使用RabbitMQ支持的Spring集成通道。 (由于某种原因,似乎几乎没有记录,这是新的吗?)。
为此,我似乎可以使用AmqpChannelFactoryBean来创建一个频道。 要设置消息转换,我使用Jackson2JsonMessageConverter。
当我使用带有POJO有效负载的GenericMessage时,它拒绝从Java反序列化它,主要是因为它不知道类型。我原本希望将类型自动放在标题上,但在标题上只有__TypeId__=org.springframework.messaging.support.GenericMessage
。
在Spring启动时,我的配置类如下所示:
@Configuration
public class IntegrationConfiguration {
@Bean
public MessageConverter messageConverter() {
return new Jackson2JsonMessageConverter();
}
@Bean
public AmqpChannelFactoryBean myActivateOutChannel(CachingConnectionFactory connectionFactory,
MessageConverter messageConverter) {
AmqpChannelFactoryBean factoryBean = new AmqpChannelFactoryBean(true);
factoryBean.setConnectionFactory(connectionFactory);
factoryBean.setQueueName("myActivateOut");
factoryBean.setPubSub(false);
factoryBean.setAcknowledgeMode(AcknowledgeMode.AUTO);
factoryBean.setDefaultDeliveryMode(MessageDeliveryMode.PERSISTENT);
factoryBean.setMessageConverter(messageConverter);
return factoryBean;
}
@Bean
@ServiceActivator(inputChannel = "bsnkActivateOutChannel", autoStartup="true")
public MessageHandler mqttOutbound() {
return m -> System.out.println(m);
}
}
发送方式如下:
private final MessageChannel myActivateOutChannel;
@Autowired
public MySender(MessageChannel myActivateOutChannel) {
this.myActivateOutChannel = myActivateOutChannel;
}
@Override
public void run(ApplicationArguments args) throws Exception {
MyPojo pojo = new MyPojo();
Message<MyPojo> msg = new GenericMessage<>(pojo);
myActivateOutChannel.send(msg);
}
如果我设置了自己的类映射器,事情就会发挥作用。但如果我设置这样的东西,我将不得不使用许多MessageConverters。 E.g。
converter.setClassMapper(new ClassMapper() {
@Override
public void fromClass(Class< ? > clazz, MessageProperties properties) {
}
@Override
public Class< ? > toClass(MessageProperties properties) {
return MyPojo.class;
}
});
我使用这个错了吗?我错过了一些配置吗?还有其他建议吗?
谢谢! :)
注意:更多地关注事物,我猜测了Spring集成&#39;方法是在每一侧添加一个Spring集成JSON转换器,这意味着每个RabbitMQ队列还增加两个额外的直接通道? 这对我来说是错误的,因为我已经获得了三倍的频道(6!for in / out),但可能是因为该框架应该如何使用?通过直接渠道结合所有简单的步骤? (在这种情况下,我是否保持RabbitMQ频道提供的持久性?或者,如果我需要,我是否需要一些事务处理机制?或者直接通道的工作原理是什么?)
我现在也注意到Spring-integration MessageConverter和Spring-amqp MessageConverter都有。后者是我使用的那个。对方会按照我想要的方式工作吗?快速浏览代码表明它没有将对象类型存储在消息头中吗?
答案 0 :(得分:1)
在4.3版之前,amqp支持的通道仅支持可序列化的有效负载;解决方法是使用通道适配器(支持映射)。
INT-3975引入了一个新属性extractPayload
,它会将邮件标头映射到rabbitmq标头,而邮件正文只是有效负载而不是序列化GenericMessage
。
将extractPayload
设置为true可以解决您的问题。