Начало работы с Spring JMS
1. обзор
Spring предоставляет интегрированную среду JMS, которая упрощает использование JMS API. В этой статье представлены основные концепции такой интеграции.
2. Maven Dependency
Чтобы использовать Spring JMS в нашем приложении, нам нужно добавить необходимые артефакты вpom.xml:
org.springframework
spring-jms
4.3.3.RELEASE
Самая новая версия артефакта может бытьfound here.
3. JmsTemplate
КлассJmsTemplate обрабатывает создание и освобождение ресурсов при отправке или синхронном получении сообщений.
Следовательно, класс, который использует этотJmsTemplate, должен только реализовать интерфейсы обратного вызова, как указано в определении метода.
Начиная с Spring 4.1,JmsMessagingTemplate построен поверхJmsTemplate, который обеспечивает интеграцию с абстракцией обмена сообщениями, то естьorg.springframework.messaging.Message.. Это, в свою очередь, позволяет нам создавать сообщение для отправки. в общем виде.
4. Управление подключением
Чтобы подключиться и иметь возможность отправлять / получать сообщения, нам нужно настроитьConnectionFactory.
A ConnectionFactory is one of the JMS administered objects which are preconfigured by an administrator. Клиент с помощью конфигурации установит соединение с провайдером JMS.
Spring предоставляет 2 типаConnectionFactory:
-
SingleConnectionFactory – - это реализация интерфейсаConnectionFactory, который будет возвращать одно и то же соединение для всех вызововcreateConnection () и игнорировать вызовыclose ()
-
CachingConnectionFactory – расширяет функциональностьSingleConnectionFactory и добавляет, расширяет ее с помощью кэшированияSessions,MessageProducers иMessageConsumers
5. Управление местом назначения
Как обсуждалось выше, наряду сConnectionFactory, пункты назначения также являются объектами, администрируемыми JMS, и могут храниться и извлекаться из JNDI.
Spring предоставляет общие преобразователи, такие какDynamicDestinationResolver, и специальные преобразователи, такие какJndiDestinationResolver.
JmsTemplate делегирует разрешение имени места назначения одной из реализаций на основе нашего выбора.
Он также предоставит свойство с именемdefaultDestination, которое будет использоваться с операциямиsend иreceive, которые не относятся к конкретному месту назначения.
6. Преобразование сообщений
Spring JMS был бы неполным без поддержки конвертеров сообщений.
Стратегия преобразования по умолчанию, используемаяJmsTemplate для операцийConvertAndSend() иReceiveAndConvert(), - это классSimpleMessageConverter.
The SimpleMessageConverter может обрабатыватьTextMessages,BytesMessages,MapMessages иObjectMessages. Этот класс реализует интерфейсMessageConverter.
ПомимоSimpleMessageConverter, Spring JMS предоставляет некоторые другие классыMessageConverter из коробки, напримерMappingJackson2MessageConverter,MarshallingMessageConverter,MessagingMessageConverter.
Более того, мы можем создавать собственные функции преобразования сообщений, просто реализуя методыtoMessage() иFromMessage() интерфейсаMessageConverter.
Давайте посмотрим пример фрагмента кода по реализации пользовательскогоMessageConverter,
public class SampleMessageConverter implements MessageConverter {
public Object fromMessage(Message message)
throws JMSException, MessageConversionException {
//...
}
public Message toMessage(Object object, Session session)
throws JMSException, MessageConversionException {
//...
}
}
7. Пример Spring JMS
В этом разделе мы увидим, как использоватьJmsTemplate для отправки и получения сообщений.
По умолчанию используется метод отправки сообщенияJmsTemplate.send(). Он имеет два ключевых параметра, из которых первый параметр - это место назначения JMS, а второй параметр - реализацияMessageCreator. The JmsTemplate, использующая метод обратного вызоваMessageCreator 'createMessage() для построения сообщения.
JmsTemplate.send() подходит для отправки текстовых сообщений, но для отправки пользовательских сообщенийJmsTemplate имеет другой метод, называемый convertAndSend().
Ниже мы можем увидеть реализацию этих методов:
public class SampleJmsMessageSender {
private JmsTemplate jmsTemplate;
private Queue queue;
// setters for jmsTemplate & queue
public void simpleSend() {
jmsTemplate.send(queue, s -> s.createTextMessage("hello queue world"));
}
public void sendMessage(Employee employee) {
System.out.println("Jms Message Sender : " + employee);
Map map = new HashMap<>();
map.put("name", employee.getName()); map.put("age", employee.getAge());
jmsTemplate.convertAndSend(map);
}
}
Ниже приведен класс получателя сообщений, мы называем его POJO, управляемым сообщениями (MDP). We can see that the class SampleListener is implementing the MessageListener interface and provides the text specific implementation for the interface method onMessage().с
Помимо методаonMessage(), наш классSampleListener также вызвал методreceiveAndConvert() для получения пользовательских сообщений:
public class SampleListener implements MessageListener {
public JmsTemplate getJmsTemplate() {
return getJmsTemplate();
}
public void onMessage(Message message) {
if (message instanceof TextMessage) {
try {
String msg = ((TextMessage) message).getText();
System.out.println("Message has been consumed : " + msg);
} catch (JMSException ex) {
throw new RuntimeException(ex);
}
} else {
throw new IllegalArgumentException("Message Error");
}
}
public Employee receiveMessage() throws JMSException {
Map map = (Map) getJmsTemplate().receiveAndConvert();
return new Employee((String) map.get("name"), (Integer) map.get("age"));
}
}
Мы увидели, как реализоватьMessageListener, и ниже мы видим конфигурацию в контексте приложения Spring:
DefaultMessageListenerContainer - это контейнер слушателя сообщений по умолчанию, который Spring предоставляет вместе со многими другими специализированными контейнерами.
8. Базовая конфигурация с аннотациями Java
The @JmsListener is the only annotation required to convert a method of a normal bean into a JMS listener endpoint. Spring JMS предоставляет гораздо больше аннотаций для упрощения реализации JMS.
Мы можем видеть некоторые примеры классов, аннотированные ниже:
@JmsListener(destination = "myDestination")
public void SampleJmsListenerMethod(Message order) { ... }
Чтобы добавить несколько слушателей к одному методу, нам просто нужно добавить несколько аннотаций@JmsListener.
Нам нужно добавить аннотацию@EnableJms к одному из наших классов конфигурации для поддержки аннотированных методов@JmsListener:
@Configuration
@EnableJms
public class AppConfig {
@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
DefaultJmsListenerContainerFactory factory
= new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory());
return factory;
}
}
9. Обработчик ошибок
Мы также можем настроить собственный обработчик ошибок для нашего контейнера слушателя сообщений.
Давайте сначала реализуем интерфейсorg.springframework.util.ErrorHandler:
@Service
public class SampleJmsErrorHandler implements ErrorHandler {
// ... logger
@Override
public void handleError(Throwable t) {
LOG.warn("In default jms error handler...");
LOG.error("Error Message : {}", t.getMessage());
}
}
Обратите внимание, что мы переопределили методhandleError(), который просто регистрирует сообщение об ошибке.
Затем нам нужно сослаться на нашу службу обработчика ошибок вDefaultJmsListenerConnectionFactory, используя методsetErrorHandler():
@Bean
public DefaultJmsListenerContainerFactorybjmsListenerContainerFactory() {
DefaultJmsListenerContainerFactory factory
= new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory());
factory.setErrorHandler(sampleJmsErrorHandler);
return factory;
}
Теперь наш настроенный обработчик ошибок будет перехватывать все необработанные исключения и записывать сообщение.
При желании мы также можем настроить обработчик ошибок, используя старые конфигурации XML, обновив нашappContext.xml:
10. Заключение
В этом руководстве мы обсудили конфигурацию и основные понятия Spring JMS. Мы также вкратце рассмотрели специфичные для Spring классыJmsTemplate, которые используются для отправки и получения сообщений.
Вы можете найти реализацию кода вGitHub project.