EJB - Bean sin estado

Un bean de sesión sin estado es un tipo de enterprise bean, que normalmente se utiliza para realizar operaciones independientes. Un bean de sesión sin estado según su nombre no tiene ningún estado de cliente asociado, pero puede conservar su estado de instancia. EJB Container normalmente crea un grupo de pocos objetos de bean sin estado y usa estos objetos para procesar la solicitud del cliente. Debido al grupo, no se garantiza que los valores de las variables de instancia sean los mismos en todas las búsquedas / llamadas a métodos.

Pasos para crear un EJB sin estado

Los siguientes son los pasos necesarios para crear un EJB sin estado:

  • Cree una interfaz remota / local que exponga los métodos comerciales.

  • Esta interfaz será utilizada por la aplicación cliente EJB.

  • Utilice la anotación @Local, si el cliente EJB está en el mismo entorno en el que se desplegará el bean de sesión EJB.

  • Utilice la anotación @Remote, si el cliente EJB se encuentra en un entorno diferente donde se desplegará el bean de sesión EJB.

  • Cree un bean de sesión sin estado, implementando la interfaz anterior.

  • Utilice la anotación @Stateless para indicar que es un bean sin estado. EJB Container crea automáticamente las configuraciones o interfaces relevantes requeridas leyendo esta anotación durante la implementación.

Interfaz remota

import javax.ejb.Remote;
 
@Remote
public interface LibrarySessionBeanRemote {
   //add business method declarations
}

EJB sin estado

@Stateless
public class LibrarySessionBean implements LibrarySessionBeanRemote {
   //implement business method 
}

Aplicación de ejemplo

Creemos una aplicación EJB de prueba para probar EJB sin estado.

Paso Descripción
1

Cree un proyecto con un nombre EjbComponent en un paquete com.tutorialspoint.stateless 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 EJB sin estado.

2

Cree LibrarySessionBean.java y LibrarySessionBeanRemote como se explica en el capítulo EJB - Crear aplicación . Mantenga el resto de los archivos sin cambios.

3

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

4

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.

5

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.

EJBComponent (módulo EJB)

LibrarySessionBeanRemote.java

package com.tutorialspoint.stateless;
 
import java.util.List;
import javax.ejb.Remote;
 
@Remote
public interface LibrarySessionBeanRemote {
   void addBook(String bookName);
   List getBooks();
}

LibrarySessionBean.java

package com.tutorialspoint.stateless;
 
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
 
@Stateless
public class LibrarySessionBean implements LibrarySessionBeanRemote {
    
   List<String> bookShelf;    
 
   public LibrarySessionBean() {
      bookShelf = new ArrayList<String>();
   }
 
   public void addBook(String bookName) {
      bookShelf.add(bookName);
   }    
 
   public List<String> getBooks() {
      return bookShelf;
   }
}
  • Tan pronto como implemente el proyecto EjbComponent en JBOSS, observe el registro de jboss.

  • JBoss ha creado automáticamente una entrada JNDI para nuestro bean de sesión - LibrarySessionBean/remote.

  • Usaremos esta cadena de búsqueda para obtener un objeto comercial remoto de tipo: com.tutorialspoint.stateless.LibrarySessionBeanRemote

Salida de registro del servidor de aplicaciones JBoss

...
16:30:01,401 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
   LibrarySessionBean/remote - EJB3.x Default Remote Business Interface
   LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibrarySessionBean,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibrarySessionBeanRemote ejbName: LibrarySessionBean
16:30:02,731 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
 
   LibrarySessionBean/remote - EJB3.x Default Remote Business Interface
   LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote - EJB3.x Remote Business Interface
...

EJBTester (cliente EJB)

jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
  • Estas propiedades se utilizan para inicializar el objeto InitialContext del servicio de nombres de Java.

  • El objeto InitialContext se utilizará para buscar un bean de sesión sin estado.

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.stateful.LibrarySessionBeanRemote;
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.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.testStatelessEjb();
   }
   
   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 testStatelessEjb() {
 
      try {
         int choice = 1; 
 
         LibrarySessionBeanRemote libraryBean =
         LibrarySessionBeanRemote)ctx.lookup("LibrarySessionBean/remote");
 
         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);
               libraryBean.addBook(book);          
            } else if (choice == 2) {
               break;
            }
         }
 
         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++;
         }       
         LibrarySessionBeanRemote libraryBean1 = 
            (LibrarySessionBeanRemote)ctx.lookup("LibrarySessionBean/remote");
         List<String> booksList1 = libraryBean1.getBooks();
         System.out.println(
            "***Using second lookup to get library stateless object***");
         System.out.println(
            "Book(s) entered so far: " + booksList1.size());
         for (int i = 0; i < booksList1.size(); ++i) {
            System.out.println((i+1)+". " + booksList1.get(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 testStatelessEjb (), la búsqueda de jndi se realiza con el nombre - "LibrarySessionBean / remote" para obtener el objeto comercial remoto (ejb sin estado).

  • 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 guarda el libro usando el método addBook () del bean de sesión sin estado. Session Bean está almacenando el libro en su variable de instancia.

  • Si el usuario ingresa 2, el sistema recupera los libros usando el método getBooks () del bean de sesión sin estado y sale.

  • Luego, se realiza otra búsqueda de jndi con el nombre - "LibrarySessionBean / remote" para obtener el objeto comercial remoto (EJB sin 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 Java
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 1
1. Learn Java
***Using second lookup to get library stateless object***
Book(s) entered so far: 0
BUILD SUCCESSFUL (total time: 13 seconds)

Ejecute el cliente nuevamente 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: 2
Book(s) entered so far: 0
***Using second lookup to get library stateless object***
Book(s) entered so far: 1
1. Learn Java
BUILD SUCCESSFUL (total time: 12 seconds)
  • La salida que se muestra arriba puede variar, dependiendo de cuántos objetos EJB sin estado mantenga JBoss.

  • En caso de que se mantenga un único objeto EJB sin estado, es posible que vea la misma lista de libros después de cada búsqueda.

  • EJB Container puede devolver el mismo objeto EJB sin estado para cada búsqueda.

  • El bean EJB sin estado mantiene el valor de la variable de instancia hasta que no se reinicia el servidor.