Что такое обратный вызов JmsTemplate в Spring JMS?
Я впервые с Spring JMS (и с JMS в целом), и у меня есть некоторые сомнения, связанные с концепцией обратного вызова JmsTemplate.
Я знаю, что JmsTemplate - это класс, предоставляемый из Spring для:
- Уменьшает шаблонный код.
- Управляет ресурсами прозрачно.
- Преобразует проверенные исключения в эквиваленты времени выполнения.
- Предоставляет удобные методы и обратные вызовы.
и что он используется для производства сообщений и синхронного приема сообщений. Это упрощает использование JMS, поскольку оно обрабатывает создание и освобождение ресурсов при отправке или синхронном получении сообщений.
Читая официальную документацию Spring (здесь: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/jms.html) я обнаружил:
Код, который использует JmsTemplate, должен только реализовать интерфейсы обратного вызова, дающие им четко определенный высокоуровневый контракт. Интерфейс обратного вызова MessageCreator создает сообщение с указанием сеанса, предоставляемого вызывающим кодом в JmsTemplate.
Это не ясно для меня. Что именно это обратный вызов?
Вначале я думал, что обратный вызов - это метод, предоставленный из JmsTemplate, но, читая здесь, он кажется чем-то более похожим на интерфейс, который я должен реализовать. Как это устроено?
Я также нашел этот пример:
ОТПРАВКА POJO ЧЕРЕЗ JMS (используя JmsTemplate):
public class JmsOrderManager implements OrderManager {
@Autowired JmsTemplate jmsTemplate;
@Autowired Destination orderQueue;
public void placeOrder(Order order) {
String stringMessage = "New order " + order.getNumber();
jmsTemplate.convertAndSend("messageQueue", stringMessage );
// use destination resolver and message converter
jmsTemplate.convertAndSend(orderQueue, order); // use message converter
jmsTemplate.convertAndSend(order); // use converter and default destination
}
}
Я думал, что метод convertAndSend() является обратным вызовом JmsTemplate, но, вероятно, это утверждение неверно.
Можете ли вы объяснить мне, что такое обратный вызов JmsTemplate?
2 ответа
Принцип проектирования, общий для шаблонных классов Spring, заключается в предоставлении вспомогательных методов для выполнения общих операций и для более сложного использования, делегирования сути задачи обработки реализованным пользователем интерфейсам обратного вызова.
В JMS соединение будет получено с завода
=> Из этого сеанса связи создается сеанс, является единицей работы, он также обеспечивает транзакцию
=> из сеанса вы создаете различные типы JMS-сообщений, такие как TextMessage, ObjectMessage, MapMessage, BytesMessage и StreamMessage, следующими способами session.createTextMessage("hello queue world"); session.createObjectMessage(someSerializedObject) и т. д.
=> Тот же сеанс также отвечает за создание экземпляра MessageProducer session.createProducer(назначение) и MessageConsumer session.createConsumer(назначение)
У вас есть следующие возможности convertAndSend (перегруженные методы):
jmsTemplate.convertAndSend(message)
jmsTemplate.convertAndSend(destination, message)
jmsTemplate.convertAndSend(message, postProcessor)
jmsTemplate.convertAndSend(destinationName, message)
jmsTemplate.convertAndSend(destination, message, postProcessor)
jmsTemplate.convertAndSend(destinationName, message, postProcessor)
Что происходит? Основное использование обратного вызова, такого как 3-я 5-я и 6-я подпись, заключается в том, что вы можете изменить сообщение после преобразования объекта в сообщение JMS через настроенный MessageConverter. Вы видите фактическое назначение, которое должно быть разрешено с помощью DestinationResolver в случае 6-го, вы не передаете его, оно будет разрешено из JNDI, если оно зарегистрировано там.
Что это значит?
jmsTemplate.send(this.queue, new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage("hello queue world");
}
});
Здесь, в этом примере, вы видите, что с методом send() шаблона JMS вы предоставляете анонимную реализацию (обратный вызов), где метод дает вам доступ к объекту сеанса, и из этого сеанса вы создали настроенный файл session.createTextMessage ("hello queue world") сообщение.
То же самое в convertAndSend (вы можете получить доступ к постпроцессорам для изменения)
public void ConvertSend() {
Map map = new HashMap();
map.put("Name", "Vimal");
map.put("Age", new Integer(45));
jmsTemplate.convertAndSend("jmsQueue", map, new MessagePostProcessor() {
public Message postProcessMessage(Message message) throws JMSException {
message.setIntProperty("ID", 9999);
message.setJMSCorrelationID("123-99999");
return message;
}
});
}
Объект сообщения был создан, но вы изменяете его (добавляя еще два свойства, в дополнение к имени и возрасту). Интерфейс MessagePostProcessor предоставляет вам доступ к сообщению после его преобразования, но до его отправки.
Другими словами! установка свойств сообщения, заголовков и тела не может быть инкапсулирована внутри класса конвертера (SimpleMessageConverter), но интерфейс MessagePostProcessor предоставляет вам доступ к сообщению после того, как оно было преобразовано, но перед отправкой.
Это позволяет вам низкоуровневый доступ к объектам JMS (например, к Session
в SessionCallback
с помощью execute()
), при этом все еще надежно высвобождая ресурсы после завершения операции.