EJB - Beans controlados por mensajes

Un bean controlado por mensajes es un tipo de enterprise bean, que es invocado por el contenedor EJB cuando recibe un mensaje de una cola o un tema. El bean controlado por mensajes es un bean sin estado y se utiliza para realizar tareas de forma asíncrona.

Para demostrar el uso del bean controlado por mensajes, haremos uso del capítulo de persistencia EJB y debemos realizar las siguientes tareas:

  • Step 1- Crear tabla en la base de datos (consulte el capítulo EJB-Persistencia ).

  • Step 2- Cree la clase de entidad correspondiente a la tabla (consulte el capítulo EJB-Persistencia ).

  • Step 3- Crear fuente de datos y unidad de persistencia (consulte el capítulo EJB-Persistencia ).

  • Step 4- Cree un EJB sin estado que tenga una instancia de EntityManager (consulte el capítulo EJB-Persistencia ).

  • Step 5- Actualice los métodos ejb.Add sin estado para agregar registros y obtener registros de la base de datos a través del administrador de entidades (consulte el capítulo EJB-Persistencia ).

  • Step 6 - Crea una cola llamada BookQueue en JBoss default directorio de la aplicación.

  • Step 7 - Un cliente de aplicación basado en consola enviará un mensaje a esta cola.

  • Step 8 - Cree un bean controlado por mensajes, que utilizará el bean sin estado para conservar los datos del cliente.

  • Step 9 - El contenedor EJB de jboss llamará al bean controlado por mensaje anterior y le pasará el mensaje que el cliente enviará.

Crear cola

Cree un archivo llamado jbossmq-destinos-service.xml si no existe en <JBoss Installation Folder> > server > default > deploy carpeta.

Aquí estamos creando una cola llamada BookQueue -

jbossmq-destinos-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>

Cuando inicie JBoss, verá una entrada similar en el registro de jboss.

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

Crear bean basado en mensajes

@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 está anotado con la anotación @MessageDriven para marcarlo como bean controlado por mensajes.

  • Sus propiedades se definen como destinationType - Queue and destination - / queue / BookQueue.

  • Implementa la interfaz MessageListener, que expone el método onMessage.

  • Tiene MessgeDrivenContext como recurso.

  • El bean sin estado LibraryPersistentBeanRemote se inyecta en este bean para fines de persistencia.

Cree el proyecto EjbComponent e impleméntelo en JBoss. Después de construir e implementar el módulo EJB, necesitamos un cliente para enviar un mensaje a la cola de jboss.

Aplicación de ejemplo

Creemos una aplicación EJB de prueba para probar Message Driven Bean.

Paso Descripción
1

Cree un proyecto con un nombre EjbComponent en un paquete com.tutorialspoint.entity como se explica en el capítulo EJB - Crear aplicación . También puede utilizar el proyecto creado en el capítulo EJB - Crear aplicación como tal para este capítulo para comprender los conceptos de persistencia de EJB.

2

Cree Book.java en el paquete com.tutorialspoint.entity como se creó en el capítulo EJB-Persistence .

3

Cree LibraryPersistentBean.java y LibraryPersistentBeanRemote como se creó en el capítulo EJB-Persistence .

4

Cree jboss-ds.xml enEjbComponent > setup carpeta y persistence.xml enEjbComponent > src > conf carpeta. Estas carpetas se pueden ver en la pestaña de archivos en Netbeans como se creó en el capítulo EJB-Persistence .

5

Cree LibraryMessageBean.java en un paquete com.tutorialspoint.messagebean y modifíquelo como se muestra a continuación.

6

Crear BookQueue cola en Jboss como se describe anteriormente.

7

Limpie y compile la aplicación para asegurarse de que la lógica empresarial funcione según los requisitos.

8

Finalmente, implemente la aplicación en forma de archivo jar en JBoss Application Server. El servidor de aplicaciones JBoss se iniciará automáticamente si aún no se ha iniciado.

9

Ahora cree el cliente EJB, una aplicación basada en consola de la misma manera que se explica en el capítulo EJB - Crear aplicación en el temaCreate Client to access EJB. Modifíquelo como se muestra a continuación.

EJBComponent (módulo 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 (cliente 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 realiza las siguientes tareas:

  • Cargue las propiedades de jndi.properties e inicialice el objeto InitialContext.

  • En el método testStatefulEjb (), la búsqueda de jndi se realiza con el nombre - "/ queue / BookQueue" para obtener la referencia de la cola disponible en Jboss. Luego, el remitente se crea usando la sesión de cola.

  • Luego, se muestra al usuario una interfaz de usuario de la tienda de la biblioteca y se le pide que ingrese la opción.

  • Si el usuario ingresa 1, el sistema solicita el nombre del libro y el remitente envía el nombre del libro a la cola. Cuando el contenedor JBoss recibe este mensaje en la cola, llama al método onMessage de nuestro bean controlado por mensajes. Nuestro bean controlado por mensajes guarda el libro usando el método addBook () del bean de sesión con estado. Session Bean mantiene el libro en la base de datos a través de la llamada EntityManager.

  • Si el usuario ingresa 2, entonces se realiza otra búsqueda jndi con el nombre - "LibraryStatefulSessionBean / remote" para obtener el objeto comercial remoto (EJB con estado) nuevamente y se realiza la lista de libros.

Ejecute el cliente para acceder a EJB

Busque EJBTester.java en el explorador de proyectos. Haga clic derecho en la clase EJBTester y seleccionerun file.

Verifique la siguiente salida en la consola de 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)

El resultado que se muestra arriba indica que nuestro bean controlado por mensajes está recibiendo el mensaje y almacenando el libro en almacenamiento persistente y los libros se recuperan de la base de datos.