Учебники

EJB — бобы, управляемые сообщениями

Управляемый сообщениями компонент — это тип корпоративного компонента, который вызывается контейнером EJB при получении сообщения из очереди или темы. Компонент, управляемый сообщениями, является компонентом без сохранения состояния и используется для асинхронного выполнения задачи.

Чтобы продемонстрировать использование bean-объекта, управляемого сообщениями, мы будем использовать главу EJB-persistence, и нам нужно выполнить следующие задачи:

  • Шаг 1 — Создать таблицу в базе данных (см. Главу EJB-Persistence ).

  • Шаг 2 — Создайте класс Entity, соответствующий таблице (см. Главу EJB-Persistence ).

  • Шаг 3 — Создание источника данных и модуля постоянства (см. Главу EJB-Постоянство ).

  • Шаг 4 — Создайте EJB без сохранения состояния с экземпляром EntityManager (см. Главу EJB-Persistence ).

  • Шаг 5 — Обновите ejb без сохранения состояния. Добавьте методы, чтобы добавлять записи и получать записи из базы данных через менеджер сущностей (см. Главу EJB-Persistence ).

  • Шаг 6 — Создайте очередь с именем BookQueue в каталоге приложения JBoss по умолчанию .

  • Шаг 7 — Клиент консольного приложения отправит сообщение в эту очередь.

  • Шаг 8 — Создайте компонент, управляемый сообщениями, который будет использовать компонент без сохранения состояния для сохранения данных клиента.

  • Шаг 9 — EJB-контейнер jboss вызовет указанный выше управляемый компонентом bean и передаст ему сообщение, на которое клиент будет отправлять.

Шаг 1 — Создать таблицу в базе данных (см. Главу EJB-Persistence ).

Шаг 2 — Создайте класс Entity, соответствующий таблице (см. Главу EJB-Persistence ).

Шаг 3 — Создание источника данных и модуля постоянства (см. Главу EJB-Постоянство ).

Шаг 4 — Создайте EJB без сохранения состояния с экземпляром EntityManager (см. Главу EJB-Persistence ).

Шаг 5 — Обновите ejb без сохранения состояния. Добавьте методы, чтобы добавлять записи и получать записи из базы данных через менеджер сущностей (см. Главу EJB-Persistence ).

Шаг 6 — Создайте очередь с именем BookQueue в каталоге приложения JBoss по умолчанию .

Шаг 7 — Клиент консольного приложения отправит сообщение в эту очередь.

Шаг 8 — Создайте компонент, управляемый сообщениями, который будет использовать компонент без сохранения состояния для сохранения данных клиента.

Шаг 9 — EJB-контейнер jboss вызовет указанный выше управляемый компонентом bean и передаст ему сообщение, на которое клиент будет отправлять.

Создать очередь

Создайте файл с именем jbossmq-destination-service.xml, если он не существует в <Папке установки JBoss>> сервер> default> папка развертывания .

Здесь мы создаем очередь с именем BookQueue —

JBossMQ-направления-service.xml

<mbean code="org.jboss.mq.server.jmx.Queue"  
   name="jboss.mq.destination:service=Queue,name=BookQueue">  
   <depends optional-attribute-name="DestinationManager">
      jboss.mq:service=DestinationManager
   </depends>  
</mbean>  

Когда вы запустите JBoss, вы увидите похожую запись в журнале jboss.

...
10:37:06,167 INFO  [QueueService] Queue[/queue/BookQueue] started, fullSize=200000, pageSize=2000, downCacheSize=2000
...

Создать сообщение управляемый компонент

@MessageDriven(
   name = "BookMessageHandler",
   activationConfig = {
      @ActivationConfigProperty( propertyName = "destinationType", 
                                 propertyValue = "javax.jms.Queue"),
      @ActivationConfigProperty( propertyName = "destination", 
                                 propertyValue ="/queue/BookQueue")
   }
)
public class LibraryMessageBean implements MessageListener {
 
   @Resource
   private MessageDrivenContext mdctx;  
 
   @EJB
   LibraryPersistentBeanRemote libraryBean;
 
   public LibraryMessageBean() {        
   }
 
   public void onMessage(Message message) {
   }
}
  • LibraryMessageBean помечен аннотацией @MessageDriven, чтобы пометить его как компонент, управляемый сообщениями.

  • Его свойства определены как destinationType — Queue и destination — / queue / BookQueue.

  • Он реализует интерфейс MessageListener, который предоставляет метод onMessage.

  • Он имеет MessgeDrivenContext в качестве ресурса.

  • Компонент LibraryPersistentBeanRemote без сохранения состояния внедряется в этот компонент для сохранения.

LibraryMessageBean помечен аннотацией @MessageDriven, чтобы пометить его как компонент, управляемый сообщениями.

Его свойства определены как destinationType — Queue и destination — / queue / BookQueue.

Он реализует интерфейс MessageListener, который предоставляет метод onMessage.

Он имеет MessgeDrivenContext в качестве ресурса.

Компонент LibraryPersistentBeanRemote без сохранения состояния внедряется в этот компонент для сохранения.

Создайте проект EjbComponent и разверните его на JBoss. После сборки и развертывания модуля EJB нам нужен клиент для отправки сообщения в очередь jboss.

Пример приложения

Давайте создадим тестовое EJB-приложение для тестирования Message Driven Bean.

шаг Описание
1

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.entity, как описано в главе EJB — Создание приложения . Вы также можете использовать проект, созданный в главе EJB — Создание приложения как таковой, для понимания концепций персистентности EJB.

2

Создайте Book.java в пакете com.tutorialspoint.entity, как он был создан в главе EJB-Persistence .

3

Создайте LibraryPersistentBean.java и LibraryPersistentBeanRemote, как они были созданы в главе EJB-Persistence .

4

Создайте jboss-ds.xml в EjbComponent> установочной папке и persistence.xml в EjbComponent> src> conf . Эти папки можно увидеть на вкладке файлов в Netbeans, как они созданы в главе EJB-Persistence .

5

Создайте LibraryMessageBean.java в пакете com.tutorialspoint.messagebean и измените его, как показано ниже.

6

Создайте очередь BookQueue в Jboss, как описано выше.

7

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

8

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

9

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» . Измените его, как показано ниже.

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.entity, как описано в главе EJB — Создание приложения . Вы также можете использовать проект, созданный в главе EJB — Создание приложения как таковой, для понимания концепций персистентности EJB.

Создайте Book.java в пакете com.tutorialspoint.entity, как он был создан в главе EJB-Persistence .

Создайте LibraryPersistentBean.java и LibraryPersistentBeanRemote, как они были созданы в главе EJB-Persistence .

Создайте jboss-ds.xml в EjbComponent> установочной папке и persistence.xml в EjbComponent> src> conf . Эти папки можно увидеть на вкладке файлов в Netbeans, как они созданы в главе EJB-Persistence .

Создайте LibraryMessageBean.java в пакете com.tutorialspoint.messagebean и измените его, как показано ниже.

Создайте очередь BookQueue в Jboss, как описано выше.

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» . Измените его, как показано ниже.

EJBComponent (модуль EJB)

LibraryMessageBean.java

package com.tutorialspoint.messagebean;
 
import com.tutorialspoint.entity.Book;
import com.tutorialspoint.stateless.LibraryPersistentBeanRemote;
import javax.annotation.Resource;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.EJB;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenContext;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
 
@MessageDriven(
   name = "BookMessageHandler",
   activationConfig = {
      @ActivationConfigProperty( propertyName = "destinationType", 
                                 propertyValue = "javax.jms.Queue"),
      @ActivationConfigProperty( propertyName = "destination", 
                                 propertyValue ="/queue/BookQueue")
   }
)
public class LibraryMessageBean implements MessageListener {
 
   @Resource
   private MessageDrivenContext mdctx;  
 
   @EJB
   LibraryPersistentBeanRemote libraryBean;
 
   public LibraryMessageBean() {        
   }
 
   public void onMessage(Message message) {
      ObjectMessage objectMessage = null;
      try {
         objectMessage = (ObjectMessage) message;
         Book book = (Book) objectMessage.getObject(); 
         libraryBean.addBook(book);
 
      } catch (JMSException ex) {
         mdctx.setRollbackOnly();
      }       
   }   
}

EJBTester (клиент EJB)

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.entity.Book;
import com.tutorialspoint.stateless.LibraryPersistentBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.naming.InitialContext;
import javax.naming.NamingException;
 
public class EJBTester {
 
   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {
 
      EJBTester ejbTester = new EJBTester();
 
      ejbTester.testMessageBeanEjb();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testMessageBeanEjb() {
 
      try {
         int choice = 1; 
         Queue queue = (Queue) ctx.lookup("/queue/BookQueue");
         QueueConnectionFactory factory =
         (QueueConnectionFactory) ctx.lookup("ConnectionFactory");
         QueueConnection connection =  factory.createQueueConnection();
         QueueSession session = 
         connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
         QueueSender sender = session.createSender(queue);
 
         while (choice != 2) {
            String bookName;
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();
               Book book = new Book();
               book.setName(bookName);
               ObjectMessage objectMessage = 
                  session.createObjectMessage(book);
               sender.send(objectMessage); 
            } else if (choice == 2) {
               break;
            }
         }
 
         LibraryPersistentBeanRemote libraryBean = 
         (LibraryPersistentBeanRemote)
         ctx.lookup("LibraryPersistentBean/remote");
 
         List<Book> booksList = libraryBean.getBooks();
 
         System.out.println("Book(s) entered so far: " + booksList.size());
         int i = 0;
         for (Book book:booksList) {
            System.out.println((i+1)+". " + book.getName());
            i++;
         }           
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }   
}

EJBTester выполняет следующие задачи —

  • Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

  • В методе testStatefulEjb () поиск jndi выполняется с именем — «/ queue / BookQueue», чтобы получить разрешение очереди, доступной в Jboss. Затем отправитель создается с использованием сеанса очереди.

  • Затем пользователю показывается пользовательский интерфейс магазина библиотеки, и ему / ей предлагается ввести выбор.

  • Если пользователь вводит 1, система запрашивает имя книги, а отправитель отправляет имя книги в очередь. Когда контейнер JBoss получает это сообщение в очереди, он вызывает метод onMessage нашего бина, управляемого сообщениями. Наш компонент, управляемый сообщениями, затем сохраняет книгу, используя метод addBook () сессионного компонента с сохранением состояния. Сессионный компонент сохраняет книгу в базе данных с помощью вызова EntityManager.

  • Если пользователь вводит 2, тогда выполняется другой поиск jndi с именем — «LibraryStatefulSessionBean / remote», чтобы снова получить удаленный бизнес-объект (EJB с сохранением состояния) и выполнить распечатку книг.

Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

В методе testStatefulEjb () поиск jndi выполняется с именем — «/ queue / BookQueue», чтобы получить разрешение очереди, доступной в Jboss. Затем отправитель создается с использованием сеанса очереди.

Затем пользователю показывается пользовательский интерфейс магазина библиотеки, и ему / ей предлагается ввести выбор.

Если пользователь вводит 1, система запрашивает имя книги, а отправитель отправляет имя книги в очередь. Когда контейнер JBoss получает это сообщение в очереди, он вызывает метод onMessage нашего бина, управляемого сообщениями. Наш компонент, управляемый сообщениями, затем сохраняет книгу, используя метод addBook () сессионного компонента с сохранением состояния. Сессионный компонент сохраняет книгу в базе данных с помощью вызова EntityManager.

Если пользователь вводит 2, тогда выполняется другой поиск jndi с именем — «LibraryStatefulSessionBean / remote», чтобы снова получить удаленный бизнес-объект (EJB с сохранением состояния) и выполнить распечатку книг.

Запустите клиент для доступа к EJB

Найдите EJBTester.java в проводнике проекта. Щелкните правой кнопкой мыши класс EJBTester и выберите файл запуска .

Проверьте следующий вывод в консоли Netbeans —

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Learn EJB
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 2
1. learn java
1. learn EJB
BUILD SUCCESSFUL (total time: 15 seconds)

Вывод, показанный выше, говорит о том, что управляемый сообщениями bean-компонент получает сообщение и сохраняет книгу в постоянном хранилище, а книги извлекаются из базы данных.