Изучаем Java EE 7 - [206]

Шрифт
Интервал

• синхронно — приемник явно получает сообщение от адресанта, вызвав метод receive();

• асинхронно — приемник решает зарегистрироваться на получение события, которое срабатывает всякий раз, когда появляется сообщение; он должен реализовать интерфейс MessageListener, и, когда приходит сообщение, поставщик доставляет его, вызвав метод onMessage().

На рис. 13.10 показаны эти два типа потребителя.


Рис. 13.10. Синхронные и асинхронные потребители

Синхронная доставка

Синхронный потребитель должен запустить JMSContext, работать в цикле, пока не придет новое сообщение, и запросить полученное сообщение с помощью одного из методов receive() (см. табл. 13.6). Есть несколько вариантов метода receive(), которые позволяют клиенту получить сообщение или подождать следующего. Описанные далее шаги объясняют, как создать синхронного потребителя, который потребляет сообщение из очереди (листинг 13.7).

1. Получить фабрику соединений и тему, используя поиск JNDI (или внедрение).

2. Создать объект JMSContext с помощью фабрики соединений.

3. Создать javax.jms.JMSConsumer посредством объекта JSMContext.

4. Запустить цикл и вызвать метод receive() (или в данном случае receiveBody) объекта-потребителя. Методы receive() будут заблокированы, если очередь пуста, и станут ждать прибытия сообщения. Здесь бесконечный цикл ждет появления других сообщений.


Листинг 13.7. Класс-потребитель потребляет сообщения в синхронном режиме

>public class Consumer {

>··public static void main(String[] args) {

>····try {

>······// Получение контекста JNDI

>······Context jndiContext = new InitialContext();


>······// Поиск администрируемых объектов

>······ConnectionFactory connectionFactory = (ConnectionFactory) 

>························jndiContext.lookup("jms/javaee7/ConnectionFactory");

>······Destination queue = (Destination) jndiContext.lookup("jms/javaee7/Queue");


>······// Цикл получения сообщений

>······try (JMSContext context = connectionFactory.createContext()) {

>········while (true) {

>··········String message = context.createConsumer(queue). receiveBody (String.class);

>········}

>······}


>····}··catch (NamingException e) {

>······e.printStackTrace();

>····}

>··}

>}

Опять же, сравнив этот код с приведенным ранее (см. листинг 13.3), вы увидите, насколько новый API проще в использовании и более выразителен.


Примечание

Как и в случае производителей, которые могут использовать внедрение с помощью аннотаций @Resource, @Inject или @JMSConnectionFactory при выполнении внутри контейнера (см. листинги 13.5 и 13.6), потребители могут пользоваться теми же функциональными возможностями. Здесь я просто показываю, как потребитель может получить сообщение в чистой среде Java SE, но вы можете сами придумать, как упростить код, чтобы он работал внутри контейнера и использовал внедрение.

Асинхронная доставка

Асинхронное потребление основано на обработке событий. Клиент может зарегистрировать объект (включая себя), который реализует интерфейс MessageListener. Слушатель сообщений — это объект, который выступает в качестве асинхронного обработчика события для сообщений. По мере поступления сообщений поставщик доставляет их слушателю, вызвав метод onMessage(), который принимает один аргумент типа Message. С помощью этой модели событий потребителю не нужно запускать бесконечный цикл для получения сообщения. Данную модель событий использует MDB (подробнее об этом — позже).

Следующие шаги описывают процесс создания асинхронного слушателя сообщений (листинг 13.8).

1. Реализация классом интерфейса javax.jms.MessageListener, который определяет один метод — onMessage().

2. Получение фабрики соединений и темы с использованием поиска JNDI (или внедрения).

3. Создание javax.jms.JMSConsumer с помощью объекта JSMContext.

4. Вызов метода setMessageListener() с передачей ему экземпляра интерфейса MessageListener (в листинге 13.8 сам класс Listener реализует интерфейс MessageListener).

5. Реализация метода onMessage() и обработка полученных сообщений. Каждый раз, когда приходит сообщение, поставщик будет вызывать этот метод, передавая сообщение.


Листинг 13.8. Потребитель является слушателем сообщений

>public class Listener implements MessageListener {

>··public static void main(String[] args) {


>····try {

>·····// Получение контекста JNDI

>······Context jndiContext = new InitialContext();


>······// Поиск администрируемых объектов

>······ConnectionFactory connectionFactory = (ConnectionFactory) 

>························jndiContext.lookup("jms/javaee7/ConnectionFactory");

>······Destination queue = (Destination) jndiContext.lookup("jms/javaee7/Queue");


>······try (JMSContext context = connectionFactory.createContext()) {

>········context.createConsumer(queue). setMessageListener(new Listener());

>······}


>····}··catch (NamingException e) {

>······e.printStackTrace();

>····}

>··}


>··public void onMessage(Message message) {

>····System.out.println("Асинхронное сообщение получено: " + 

>·······················message.getBody(String.class));

>··}

>}

Механизмы надежности

Вы уже знаете, как подключаться к провайдеру, создавать различные типы сообщений, отправлять их в очереди или темы и получать их. Однако что, если вы сильно зависите от JMS и вам необходимо обеспечить надежность или другие дополнительные функции? JMS определяет несколько уровней надежности, которые обеспечивают доставку ваших сообщений, даже если поставщик выйдет из строя, или будет слишком загружен, или если место назначения уже заполнено сообщениями, срок жизни которых должен был истечь? Механизмы достижения надежной доставки сообщений следующие:


Рекомендуем почитать
Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


MFC и OpenGL

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Симуляция частичной специализации

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Обработка событий в С++

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.