Данный текст является вольным переводом начала статьи Найджела Дикина. Текст предназначен для ознакомления заинтересованного читателя с новым API.
API JMS 1.1 требует для работы достаточно много кода, но успело себя хорошо зарекомендовать, потому, с 2002 года не изменялось. В JMS 2.0 новое API призвано упростить отправку и прием JMS-сообщений. Прежнее API не упраздняется и продолжает работать наравне с новым.
В API JMS 2.0 появились новые интерфейсы: JMSContext, JMSProducer и JMSConsumer.
- JMSContext заменяет Connection и Session в классиеском JMS API
- JMSProducer — это легковесная замена MessageProducer-у, которая позволяет задавать настройки доставки сообщений, заголовки, свойства, через вызов цепочки методов (паттерн Строитель)
- JMSConsumer заменяет MessageConsumer и используется по такому же принципу
Отправка JMS
Для сравнения. JMS 1.1:
public void sendMessageJMS11(ConnectionFactory connectionFactory, Queue queue, String text) { try { Connection connection = connectionFactory.createConnection(); try { Session session =connection.createSession(false,Session.AUTO_ACKNOWLEDGE); MessageProducer messageProducer = session.createProducer(queue); TextMessage textMessage = session.createTextMessage(text); messageProducer.send(textMessage); } finally { connection.close(); } } catch (JMSException ex) { // handle exception (details omitted) } }
JMS 2.0:
public void sendMessageJMS20(ConnectionFactory connectionFactory, Queue queue, String text) { try (JMSContext context = connectionFactory.createContext();){ context.createProducer().send(queue, text); } catch (JMSRuntimeException ex) { // handle exception (details omitted) } }
- В версии 2.0 мы используем try-with-resources из JavaSE 7
- Параметр Session.AUTO_ACKNOWLEDGE устанавливается по умолчанию в JMSContext. Если требуется установить другое значение (CLIENT_ACKNOWLEDGE или DUPS_OK_ACKNOWLEDGE), оно передается как отдельный параметр
- Используется JMSContext вместо объектов Connection и Session
- Что бы создать TextMessage достаточно просто передать в метод send строку
Отличительной особенностью нового API является то, что его методы бросают RuntimeException — JMSRuntimeException, вместо checked-исключения JMSException. Это дает возможность при желании не обрабатывать JMS-исключения.
Синхронное получение JMS
Сравниваем разницу при синхронном получении сообщений.
JMS 1.1:
public String receiveMessageJMS11(ConnectionFactory connectionFactory,Queue queue){ String body=null; try { Connection connection = connectionFactory.createConnection(); try { Session session =connection.createSession(false,Session.AUTO_ACKNOWLEDGE); MessageConsumer messageConsumer = session.createConsumer(queue); connection.start(); TextMessage textMessage = (TextMessage)messageConsumer.receive(); body = textMessage.getText(); } finally { connection.close(); } } catch (JMSException ex) { // handle exception (details omitted) } return body; }
JMS 2.0:
public String receiveMessageJMS20(ConnectionFactory connectionFactory,Queue queue){ String body=null; try (JMSContext context = connectionFactory.createContext();){ JMSConsumer consumer = session.createConsumer(queue); body = consumer.receiveBody(String.class); } catch (JMSRuntimeException ex) { // handle exception (details omitted) } return body; }
- Используется try-with-resources для автоматического закрытия соединения
- Используется JMSContext вместо объектов Connection и Session
- AUTO_ACKNOWLEDGE выставляется по умолчанию
- Обрабатывается JMSRuntimeException, который можно не обрабатывать, вместо JMSException в JMS 1.1 connection.start() выполняется автоматически
- Строка получается автоматически через метод consumer.receiveBody(String.class), вместо получения объекта Message, приведения его к TextMessage и вызова метода getText
Асинхронное получение JMS
В JavaSE, что бы получать сообщения асинхронно, в JMS 1.1 используется следующий код:
MessageConsumer messageConsumer = session.createConsumer(queue); messageConsumer.setMessageListener(messageListener); connection.start();
В JMS 2.0 это выглядит так:
JMSConsumer consumer = context.createConsumer(queue); consumer.setMessageListener(messageListener);
Вместо MessageConsumer — JMSConsumer. Соединение стартует автоматически.
В Java EE Web или EJB приложениях, как и прежде, надо использовать message-driven bean, вместо метода setMessageListener
Вставка объекта JMSContext в Java EE приложении
В Java EE приложении JMSContext можно вставить посредством аннотации Inject. После вставки JMSContext будет находиться под управлением сервера приложений.
Следующий фрагмент кода позволяет вставлять JMSContext в session bean или сервлет.
@Inject @JMSConnectionFactory( "jms/connectionFactory") private JMSContext context; @Resource(lookup = "jms/dataQueue") private Queue dataQueue; public void sendMessageJavaEE7(String body) { context.send(dataQueue, body); }
Закрытие JMSContext производится автоматически сервером приложений. Если во время запроса выполняется JTA-транзакция, то JMSContext закроется автоматически после коммита, если без транзакции, то закроется в конце запроса.
На этом я решил остановиться. Для ознакомления и начала работы этой информации должно быть достаточно. Много детаей и дополнительной информации тут:
What’s New in JMS 2.0, Part One: Ease of Use
What’s New in JMS 2.0, Part Two—New Messaging Features
ссылка на оригинал статьи http://habrahabr.ru/post/184460/
Добавить комментарий