@Override
public void sendOrder(Order order) {
jms.send(
"tacocloud.order.queue",
session -> session.createObjectMessage(order));
}
Хотя метод send() не особенно сложен в использовании (особенно, когда MessageCreator задается как лямбда-выражение), добавляется небольшая сложность, требующая предоставления MessageCreator. Разве не проще, если вам нужно только указать объект, который должен быть отправлен (и, возможно, пункт назначения)? Это кратко описывает, как работает convertAndSend (). Давайте взглянем.
Конвертация сообщения перед отправкой
Метод convertAndSend() в JmsTemplates упрощает публикацию сообщений, устраняя необходимость предоставлять MessageCreator. Вместо этого вы передаете объект, который должен быть отправлен напрямую, в convertAndSend(), и перед отправкой объект будет преобразован в Message.
Например, следующая переопределение sendOrder() использует convertAndSend() для отправки Order в заданный пункт назначения:
@Override
public void sendOrder(Order order) {
jms.convertAndSend("tacocloud.order.queue", order);
}
Как и метод send(), метод convertAndSend () примет значение Destination или String, чтобы указать адресата, или вы можете вообще не указывать адресата, чтобы отправить сообщение в пункт назначения по умолчанию.
Какую бы реализацию convertAndSend() вы ни выбрали, Order, переданный в convertAndSend(), перед отправкой преобразуется в Message. Под капотом это достигается с помощью реализации MessageConverter, которая выполняет грязную работу по преобразованию объектов в Message -ы.
НАСТРОЙКА КОНВЕРТЕРА СООБЩЕНИЙ
MessageConverter - это Spring-определнный интерфейс, который имеет только два метода для реализации:
public interface MessageConverter {
Message toMessage(Object object, Session session)
throws JMSException, MessageConversionException;
Object fromMessage(Message message)
}
Хотя этот интерфейс достаточно прост для реализации, вам часто не нужно создавать собственную реализацию. Spring уже предлагает несколько реализаций, таких как описанные в таблице 8.3.
Таблица 8.3. Spring message конвертеры для общих задач преобразования (все в пакете org.springframework.jms.support.converter)
Message конвертер - Что он делает
MappingJackson2MessageConverter - Использует Jackson 2 JSON библиотеку конвертирования сообщений в и из JSON
MarshallingMessageConverter - Использует JAXB для конвертирования сообщений в и из XML
MessagingMessageConverter - Конвертирует Message из абстракции в и из Message используя базовый MessageConverter для полезной нагрузки и JmsHeaderMapper для сопоставления заголовков JMS в и из стандартных заголовков сообщений
SimpleMessageConverter - Преобразует String в и из TextMessage, байтовые массивы в и из BytesMessage, Maps в и из MapMessage, и Serializable объекты в и из ObjectMessage.
SimpleMessageConverter является значением по умолчанию, но требует, чтобы отправляемый объект реализовывал Serializable. Это может быть хорошей идеей, но вы можете предпочесть использовать один из других конвертеров сообщений, например MappingJackson2MessageConverter, чтобы избежать этого ограничения.
Чтобы применить другой конвертер сообщений, все, что вам нужно сделать, - это объявить экземпляр выбранного конвертера как bean-компонент. Например, следующее объявление компонента позволит использовать MappingJackson2MessageConverter вместо SimpleMessageConverter:
@Bean
public MappingJackson2MessageConverter messageConverter() {
MappingJackson2MessageConverter messageConverter =
new MappingJackson2MessageConverter();
messageConverter.setTypeIdPropertyName("_typeId");
return messageConverter;
}
Обратите внимание, что вы вызвали setTypeIdPropertyName() для MappingJackson2MessageConverter, прежде чем возвращать его. Это очень важно, так как позволяет получателю знать, в какой тип конвертировать входящее сообщение. По умолчанию он будет содержать полное имя класса конвертируемого типа. Но это несколько негибко, требуя, чтобы получатель также имел тот же тип, с тем же полностью определенным именем класса.
Чтобы обеспечить большую гибкость, вы можете сопоставить синтетическое имя типа с реальным типом, вызвав setTypeIdMappings() в конвертере сообщений. Например, следующее изменение метода bean-объекта конвертера сообщений отображает синтетический идентификатор типа order в класс Order:
@Bean
public MappingJackson2MessageConverter messageConverter() {
MappingJackson2MessageConverter messageConverter =
new MappingJackson2MessageConverter();
messageConverter.setTypeIdPropertyName("_typeId");