Почему AmqpChannelFactoryBean с Jackson2JsonMessageConverter не является типом хранилища?

Я пытаюсь использовать интеграцию Spring с RabbitMQ, используя поддерживаемые RabbitMQ каналы интеграции Spring. (Что кажется почти не задокументированным по какой-то причине, это новое?).

Для этого, кажется, я могу использовать AmqpChannelFactoryBean для создания канала. Чтобы настроить преобразование сообщений, я использую Jackson2JsonMessageConverter.

Когда я использую GenericMessage с полезной нагрузкой POJO, он отказывается десериализовать его из 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, если бы я настраивал подобные вещи. Например

    converter.setClassMapper(new ClassMapper() {

        @Override
        public void fromClass(Class< ? > clazz, MessageProperties properties) {
        }

        @Override
        public Class< ? > toClass(MessageProperties properties) {
            return MyPojo.class;
        }

    });

Я использую это неправильно? Я что-то пропустил? Любые другие предложения?

Спасибо!!:)

Примечание. Если взглянуть больше на вещи, я предполагаю, что "интеграция Spring" будет заключаться в добавлении преобразователя JSON интеграции Spring с каждой стороны, что означает также добавление двух дополнительных прямых каналов в очередь RabbitMQ? Мне кажется, что это неправильно, так как у меня есть тройные каналы (6! Для входа / выхода), но, может быть, именно так предполагается использовать фреймворк? Соедините все простые шаги с прямыми каналами? (Сохраняю ли я постоянство, которое предлагают каналы RabbitMQ в этом случае? Или мне нужен какой-нибудь механизм транзакций, если я этого хочу? Или это присуще тому, как работают прямые каналы?)

Я также заметил, что теперь есть SpringConverter MessageConverter и Spring-amqp MessageConverter. Последний, который я использовал. Будет ли другой работать так, как я хочу? Быстрый взгляд на код показывает, что он не хранит тип объекта в заголовке сообщения?

1 ответ

Решение

До версии 4.3 каналы с поддержкой amqp поддерживали только сериализуемые полезные нагрузки; обходной путь заключался в том, чтобы вместо этого использовать канальные адаптеры (которые поддерживают отображение).

INT-3975 представил новое свойство extractPayload что приводит к тому, что заголовки сообщений сопоставляются с заголовками rabbitmq, а тело сообщения - это просто полезная нагрузка вместо сериализованного GenericMessage,

настройка extractPayload Истина должна решить вашу проблему.

Другие вопросы по тегам