Выбрать главу

Давайте рассмотрим оба способа получения сообщений. Начнем с pull модели, предлагаемой JmsTemplate.

ПОЛУЧЕНИЕ С JmsTemplate

JmsTemplate предлагает несколько методов для методов извлечения из брокера, включая следующие:

Message receive() throws JmsException;

Message receive(Destination destination) throws JmsException;

Message receive(String destinationName) throws JmsException;

 

Object receiveAndConvert() throws JmsException;

Object receiveAndConvert(Destination destination) throws JmsException;

Object receiveAndConvert(String destinationName) throws JmsException;

Как видите, эти шесть методов отражение методов send() и convertAndSend () из JmsTemplate. Методы receive() получают необработанное Message,  а методы receiveAndConvert() используют сконфигурированный конвертер сообщений для преобразования сообщений в типы доменов. И для каждого из них вы можете указать либо Destination, либо String, содержащую имя пункта назначения, или вы можете получить сообщение из пункта назначения по умолчанию.

Чтобы увидеть их в действии, вы напишите некоторый код, который извлекает Order из пункта назначения tacocloud.order.queue. В следующем листинге показан OrderReceiver, компонент службы, который получает данные заказа с помощью JmsTemplate.receive().

Листинг 8.2. Получение заказов из очереди

package tacos.kitchen.messaging.jms;

import javax.jms.Message;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.jms.core.JmsTemplate;

import org.springframework.jms.support.converter.MessageConverter;

import org.springframework.stereotype.Component;

@Component

public class JmsOrderReceiver implements OrderReceiver {

    private JmsTemplate jms;

    private MessageConverter converter;

    @Autowired

    public JmsOrderReceiver(JmsTemplate jms, MessageConverter converter) {

        this.jms = jms;

        this.converter = converter;

    }

    public Order receiveOrder() {

        Message message = jms.receive("tacocloud.order.queue");

        return (Order) converter.fromMessage(message);

    }

}

Здесь вы использовали String, чтобы указать пункт назначения для получения заказа. Метод receive() возвращает не конвертированный Message. Нам нужен Order, который находится внутри, Message, поэтому следующее, что происходит, - это использование конвертера сообщения для его преобразования. Свойство type ID в сообщении поможет конвертеру преобразовать его в Order, но ответ будет в виде Object, который придется  привести к нужному типу перед тем, как вы сможете его вернуть.

Получение необработанного объекта Message может быть полезно в некоторых случаях, когда вам необходимо проверить свойства и заголовки сообщения. Но часто вам нужна только полезная нагрузка. Преобразование этой полезной нагрузки в тип домена является двухэтапным процессом и требует, чтобы преобразователь сообщений был внедрен в компонент. Когда вы заботитесь только о полезной нагрузке сообщения, использовать receiveAndConvert() будет намного проще. В следующем листинге показано, как JmsOrderReceiver может быть переработан для использования receiveAndConvert () вместо receive().

Листинг 8.3 Получение преобразованного объекта Order

package tacos.kitchen.messaging.jms;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.jms.core.JmsTemplate;

import org.springframework.stereotype.Component;

@Component

public class JmsOrderReceiver implements OrderReceiver {

    private JmsTemplate jms;

    @Autowired

    public JmsOrderReceiver(JmsTemplate jms) {

        this.jms = jms;

    }

    public Order receiveOrder() {

        return (Order) jms.receiveAndConvert("tacocloud.order.queue");

    }

}

Эта новая версия JmsOrderReceiver имеет метод receieveOrder (), который был сокращен до одной строки. И вам больше не нужно внедрять MessageConverter, потому что все преобразования сообщений будут выполняться под капотом в receiveAndConvert ().

Прежде чем двигаться дальше, давайте рассмотрим, как receiveOrder() может быть использован в кухонном приложении Taco Cloud. Повар на одной из кухонь Taco Cloud может нажать кнопку или предпринять какие-либо действия, чтобы указать, что они готовы начать создание тако. В этот момент будет вызван receiveOrder(), и  вызов метода receive() или receiveAndConvert() будет заблокирован. Больше ничего не произойдет, пока сообщение о заказе не будет готово. Как только заказ поступит, он будет возвращен функцией receiveOrder(), и его информация будет использоваться для отображения деталей заказа, чтобы повар мог приступить к работе. Это кажется естественным выбором для модели тянуть (pull).