Я работал над «асфальтированной дорогой» для настройки асинхронного обмена сообщениями между двумя микросервисами с использованием AMQP. Мы хотим продвигать использование отдельных объектов домена для каждой службы, а это означает, что каждая служба должна определять свою собственную копию любых объектов, передаваемых через очередь.
Мы используем Jackson2JsonMessageConverter
как на стороне производителя, так и на стороне потребителя, и мы используем Java DSL для передачи потоков в/из очередей.
Я уверен, что есть способ сделать это, но он ускользает от меня: я хочу, чтобы сторона потребителя игнорировала заголовок __TypeID__
, который передается от производителя, поскольку потребитель может иметь другое представление этого события (и, скорее всего, находиться в другом пакете Java).
Похоже, что была проделана такая работа, что при использовании аннотации @RabbitListener
выводится аргумент inferredArgumentType
, который переопределяет информацию заголовка. Это именно то, что я хотел бы сделать, но я хотел бы использовать для этого Java DSL. Я еще не нашел чистого способа сделать это, и, возможно, я просто упускаю что-то очевидное. Кажется, было бы довольно просто вывести тип при использовании следующего DSL:
return IntegrationFlows
.from(
Amqp.inboundAdapter(factory, queueRemoteTaskStatus())
.concurrentConsumers(10)
.errorHandler(errorHandler)
.messageConverter(messageConverter)
)
.channel(channelRemoteTaskStatusIn())
.handle(listener, "handleRemoteTaskStatus")
.get();
Однако это приводит к исключению ClassNotFound
. Единственный способ, который я нашел, чтобы обойти это, — это установить собственный преобразователь сообщений, который требует явного определения типа.
public class ForcedTypeJsonMessageConverter extends Jackson2JsonMessageConverter {
ForcedTypeJsonMessageConverter(final Class<?> forcedType) {
setClassMapper(new ClassMapper() {
@Override
public void fromClass(Class<?> clazz, MessageProperties properties) {
//this class is only used for inbound marshalling.
}
@Override
public Class<?> toClass(MessageProperties properties) {
return forcedType;
}
});
}
}
Я бы очень хотел, чтобы это было выведено, поэтому разработчику не нужно особо с этим сталкиваться.
Есть ли более простой способ сделать это?
setIdClassMapping
) в преобразователе типов преобразователя. Смотрите мой ответ. - person Gary Russell   schedule 22.12.2017@RabbitListener
мы знаем тип параметра метода. При создании общего сообщения с входящей полезной нагрузкой невозможно определить тип полезной нагрузки, поскольку компонент, создающий сообщение, полностью отделен от метода, потребляющего сообщение. Следовательно, вы должны настроить преобразователь с какой-либо подсказкой для типа полезной нагрузки. Я добавил еще один вариант в свой ответ. - person Gary Russell   schedule 23.12.2017