Java Platform, Enterprise Edition (Java EE) 8
Учебник по Java EE

Назад Вперёд Содержание

Использование сущности для объединения сообщений из двух MDB

В этом разделе объясняется, как написать, скомпилировать, упаковать, развернуть и запустить приложение, которое использует JMS API с сущностью. Приложение использует следующие компоненты:

  • Клиентское приложение, которое отправляет и получает сообщения

  • Два управляемых сообщениями бина

  • Класс сущности

Вы найдете исходные файлы для этого раздела в каталоге tut-install/examples/jms/clientmdbentity/. Пути в этом разделе относятся к этому каталогу.

Здесь рассматриваются следующие темы:

Обзор примера clientmdbentity

Это приложение упрощённо моделирует рабочий процесс отдела кадров компании (HR) при найме нового сотрудника. Это приложение также демонстрирует, как использовать платформу Java EE для выполнения типовой для приложений JMS задачи.

Клиент обмена сообщениями часто должен ждать несколько сообщений из разных источников. Он использует содержимое всех этих сообщений для формирования нового сообщения, которое затем отправляет другому пункту назначения. Этот шаблон проектирования (который не является специфичным для JMS) называется объединением сообщений. Такая задача должна быть транзакционной, со всеми получениями и отправками в рамках одной транзакции. Если часть сообщений не были успешно получены, транзакцию можно откатить. Пример клиентского приложения, который иллюстрирует эту задачу, см. в разделе Использование локальных транзакций.

Компонент, управляемый сообщениями, может обрабатывать за раз только одно сообщение в транзакции. Чтобы обеспечить возможность объединения сообщений, приложение может иметь управляемый сообщениями компонент, хранящий промежуточную информацию в сущности Java Persistence API. Затем сущность может определить, была ли получена вся информация. Если это так, сущность может сообщить об этом обратно одному из управляемых сообщениями компонентов, который создаст и отправит сообщение в другой пункт назначения. После выполнения задачи сущность может быть удалена.

Основные этапы применения следующие.

  1. Клиентское приложение отдела кадров генерирует идентификатор каждого нового сотрудника, а затем публикует сообщение (M1), содержащее имя нового сотрудника, идентификатор и должность. Он публикует сообщение в теме, потому что сообщение должно быть использовано двумя компонентами, управляемыми сообщениями. Затем клиент создаёт врéменную очередь ReplyQueue со слушателем сообщений, который ожидает ответа на сообщение. (См. Создание вре́менных пунктов назначения для получения дополнительной информации.)

  2. Два управляемых сообщениями бина обрабатывают каждое сообщение: один бин, OfficeMDB, назначает номер офиса новому сотруднику, а другой бин, EquipmentMDB, назначает ему оборудование. Первый компонент, обрабатывающий сообщение, создаёт и сохраняет объект с именем SetupOffice, а затем вызывает бизнес-метод объекта для сохранения созданной им информации. Второй компонент находит существующую сущность и вызывает другой бизнес-метод для изменения её информации.

  3. Когда и офис, и оборудование были назначены, бизнес-метод объекта возвращает значение true бину, управляемому сообщениями, который вызвал метод. Затем управляемый сообщениями компонент отправляет в очередь ответов сообщение (M2), описывающее назначения. Затем он удаляет сущность. Слушатель сообщений клиентского приложения получает информацию.

Рисунок 49-5 иллюстрирует структуру этого приложения. Конечно, реальное приложение HR будет иметь больше компонентов. Другие компоненты могут настраивать учёт заработной платы и премий, расписание и т. д.

Рисунок 49-5 предполагает, что OfficeMDB является первым управляемым сообщениями компонентом, который принимает сообщение от клиента. ЗатемOfficeMDB создаёт и сохраняет объект SetupOffice и устанавливает информацию об офисе. ЗатемEquipmentMDB извлекает объект, устанавливает информацию об оборудовании и определяет, что объект закончил сбор информации. ЗатемEquipmentMDB отправляет сообщение в очередь ответов и удаляет объект.

Рис. 49-5. Приложение Enterprise Bean: клиент для управляемых сообщениями компонентов для сущности

Схема приложения с указанием клиентского приложения, двух управляемых сообщениями компонентов и сущности, а также связанной темы и очереди

Компоненты приложения clientmdbentity

Пример включает в себя клиентское приложение, управляемые сообщениями компоненты и класс сущности.

Здесь рассматриваются следующие темы:

Клиентское приложение: HumanResourceClient.java

Для создания клиентского приложения HumanResourceClient.java из clientmdbentity-app-client необходимо выполнить следующие шаги:

  1. Определить тему для приложения, используя пространство имён java:app, поскольку тема используется как в клиентском приложении, так и в модуле EJB

  2. Инъецировать ресурсы ConnectionFactory и Topic

  3. Создать TemporaryQueue для получения уведомления о происходящей обработке на основе опубликованных им событий нового найма.

  4. Создать JMSConsumer для TemporaryQueue, установить слушатель сообщений JMSConsumer-а и запустить соединение

  5. Создать MapMessage

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

Слушатель сообщений HRListener ожидает сообщений, которые содержат назначенные офис и оборудование для каждого сотрудника. Когда приходит сообщение, слушатель сообщений отображает полученную информацию и определяет, все ли пять сообщений поступили. Если да, слушатель сообщения уведомляет метод main и тот завершается.

Управляемые сообщениями компоненты примера clientmdbentity

В этом примере используются два управляемых сообщениями бина, оба в clientmdbentity-ejb:

  • EquipmentMDB.java

  • OfficeMDB.java

Бины предпринимают следующие шаги.

  1. Они инъецируют ресурсы MessageDrivenContext, EntityManager и JMSContext.

  2. Метод onMessage извлекает информацию из сообщения. Метод EquipmentMDB.onMessage выбирает оборудование для новой должности. Метод OfficeMDB.onMessage случайным образом генерирует номер офиса.

  3. После небольшой задержки (для моделирования реальных проблем обработки) метод onMessage вызывает вспомогательный метод compose.

  4. Метод compose выполняет следующие шаги.

  5. Создаёт и сохраняет объект сущности SetupOffice, либо выбирает его по первичному ключу.

  6. Использует объект для хранения оборудования или служебной информации в базе данных, вызывая либо бизнес-метод doEquipmentList, либо doOfficeNumber.

  7. Если бизнес-метод возвращает true, что означает, что вся информация была сохранена, он извлекает информацию о пункте назначения для ответа из сообщения, создаёт JMSProducer и отправляет ответное сообщение с информацией, которая содержится в объекте.

  8. Удаляет сущность.

Класс сущности примера clientmdbentity

Класс сущности SetupOffice.java находится также в clientmdbentity-ejb. Сущность и управляемые сообщениями компоненты упакованы вместе в файл JAR EJB. Класс сущности объявлен следующим образом:

@Entity
public class SetupOffice implements Serializable {

Класс содержит конструктор без аргументов и конструктор, который принимает два аргумента: идентификатор сотрудника и его имя. Он также содержит get- и set- методы для идентификатора сотрудника, его имени, номера офиса и списка оборудования. Метод получения идентификатора сотрудника имеет аннотацию @Id для указания, что это поле является первичным ключом:

@Id
public String getEmployeeId() {
    return id;
}

Класс также реализует два бизнес-метода doEquipmentList и doOfficeNumber и их вспомогательный метод checkIfSetupComplete.

Бины, управляемые сообщениями, вызывают бизнес-методы и методы получения.

В файле persistence.xml для сущности указаны основные настройки:


<persistence version="2.1"
             xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
               http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <persistence-unit name="clientmdbentity-ejbPU" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>java:comp/DefaultDataSource</jta-data-source>
    <properties>
      <property name="eclipselink.ddl-generation"
                value="drop-and-create-tables"/>
    </properties>
  </persistence-unit>
</persistence>

Запуск примера clientmdbentity

Вы можете использовать IDE NetBeans или Maven для сборки, развёртывания и запуска примера clientmdbentity.

Поскольку в примере определяется собственная тема приложения и используется предустановленная фабрика соединений по умолчанию java:comp/DefaultJMSConnectionFactory и предустановленный ресурс JDBC по умолчанию java:comp/DefaultDataSource, не нужно создавать дополнительных ресурсов.

Здесь рассматриваются следующие темы:

Запуск clientmdbentity в IDE NetBeans

  1. Убедитесь, что сервер GlassFish (см. Запуск и остановка сервера GlassFish), а также сервер базы данных (см. Запуск и остановка Apache Derby) запущены.

  2. В меню «Файл» выберите «Открыть проект».

  3. В диалоговом окне «Открыть проект» перейдите к:

    tut-install/examples/jms/clientmdbentity
  4. Выберите каталог clientmdbentity.

  5. Нажмите Открыть проект.

  6. На вкладке «Проекты» кликните правой кнопкой мыши проект clientmdbentity и выберите «Сборка».

    Эта команда создаёт следующее:

    • JAR-файл приложения-клиента, содержащий файлы класса клиента и класса слушателя, а также файл манифеста, в котором указан основной класс

    • JAR-файл EJB, содержащий управляемые сообщениями бины и класс сущностей, а также файл persistence.xml

    • Файл EAR приложения, который содержит два JAR-файла вместе с файлом application.xml

      Файл clientmdbentity.ear создаётся в каталоге clientmdbentity-ear/target/.

      Затем команда развёртывает файл EAR, извлекает клиентские заглушки и запускает клиентское приложение.

Запуск clientmdbentity с помощью Maven

  1. Убедитесь, что сервер GlassFish (см. Запуск и остановка сервера GlassFish), а также сервер базы данных (см. Запуск и остановка Apache Derby) запущены.

  2. Перейдите в следующий каталог:

    tut-install/examples/jms/clientmdbentity/
  3. Чтобы скомпилировать исходные файлы и пакет, развернуть и запустить приложение, введите следующую команду:

    mvn install

    Эта команда создаёт следующее:

    • JAR-файл приложения-клиента, содержащий файлы класса клиента и класса слушателя, а также файл манифеста, в котором указан основной класс

    • JAR-файл EJB, содержащий управляемые сообщениями бины и класс сущностей, а также файл persistence.xml

    • Файл EAR приложения, который содержит два JAR-файла вместе с файлом application.xml

      Затем команда развёртывает приложение, получает клиентские заглушки и запускает клиентское приложение.

Просмотр вывода приложения

Вывод в окне вывода IDE NetBeans или в окне терминала выглядит примерно так (ему предшествует вывод контейнера клиентского приложения и вывод Maven):

SENDER: Setting hire ID to 50, name Bill Tudor, position Programmer
SENDER: Setting hire ID to 51, name Carol Jones, position Senior Programmer
SENDER: Setting hire ID to 52, name Mark Wilson, position Manager
SENDER: Setting hire ID to 53, name Polly Wren, position Senior Programmer
SENDER: Setting hire ID to 54, name Joe Lawrence, position Director
Waiting for 5 message(s)
New hire event processed:
  Employee ID: 52
  Name: Mark Wilson
  Equipment: Tablet
  Office number: 294
Waiting for 4 message(s)
New hire event processed:
  Employee ID: 53
  Name: Polly Wren
  Equipment: Laptop
  Office number: 186
Waiting for 3 message(s)
New hire event processed:
  Employee ID: 54
  Name: Joe Lawrence
  Equipment: Mobile Phone
  Office number: 135
Waiting for 2 message(s)
New hire event processed:
  Employee ID: 50
  Name: Bill Tudor
  Equipment: Desktop System
  Office number: 200
Waiting for 1 message(s)
New hire event processed:
  Employee ID: 51
  Name: Carol Jones
  Equipment: Laptop
  Office number: 262

Вывод из бинов, управляемых сообщениями, и класса сущностей появляется в журнале сервера.

Для каждого сотрудника приложение сначала создаёт объект сущности, а затем извлекает его из хранилища. Вы можете увидеть ошибки времени выполнения в журнале сервера и произошедшие откаты соответствующих транзакций. Ошибки возникают, если оба управляемых сообщениями бина одновременно обнаруживают, что сущность ещё не существует, поэтому они оба пытаются его создать. Первая попытка успешна, но вторая — неудачна, потому что сущность уже существует. После отката и на последующей повторной попытке второй управляемый сообщениями компонент успешно извлекает сущность из хранилища. Управляемые контейнером транзакции позволяют приложению работать корректно, несмотря на эти ошибки, без специального программирования.

Чтобы удалить приложение после его завершения, перейдите на вкладку «Службы» или введите команду mvn cargo:undeploy.


Назад Вперёд Содержание
Логотип Oracle  Copyright © 2017, Oracle и/или её дочерних компаний. Все права защищены. Версия перевода 1.0.5 (Java EE Tutorial — русскоязычная версия)