EJB - Rappels

Le rappel est un mécanisme par lequel le cycle de vie d'un bean entreprise peut être intercepté. La spécification EJB 3.0 a spécifié des rappels pour lesquels des méthodes de gestionnaire de rappel sont créées. EJB Container appelle ces rappels. Nous pouvons définir des méthodes de rappel dans la classe EJB elle-même ou dans une classe distincte. EJB 3.0 a fourni de nombreuses annotations pour les rappels.

Voici la liste des annotations de rappel pour le bean sans état -

Annotation La description
@PostConstruct Appelé lorsqu'un bean est créé pour la première fois.
@PreDestroy Appelé lorsqu'un bean est retiré du pool de haricots ou est détruit.

Voici la liste des annotations de rappel pour le bean avec état -

Annotation La description
@PostConstruct Appelé lorsqu'un bean est créé pour la première fois.
@PreDestroy Appelé lorsqu'un bean est retiré du pool de haricots ou est détruit.
@PostActivate Appelé lorsqu'un bean est chargé pour être utilisé.
@PrePassivate Invoqué lorsqu'un bean est remis dans le pool de haricots.

Voici la liste des annotations de rappel pour le bean géré par message -

Annotation La description
@PostConstruct Appelé lorsqu'un bean est créé pour la première fois.
@PreDestroy Appelé lorsqu'un bean est retiré du pool de haricots ou est détruit.

Voici la liste des annotations de rappel pour le bean entité -

Annotation La description
@PrePersist Appelé lorsqu'une entité est créée dans la base de données.
@PostPersist Appelé après la création d'une entité dans la base de données.
@PreRemove Appelé lorsqu'une entité est supprimée de la base de données.
@PostRemove Appelé après la suppression d'une entité de la base de données.
@PreUpdate Appelé avant qu'une entité soit mise à jour dans la base de données.
@PostLoad Appelé lorsqu'un enregistrement est extrait de la base de données et chargé dans l'entité.

Exemple d'application

Créons une application de test EJB pour tester différents callbacks dans EJB.

Étape La description
1

Créez un projet avec un nom EjbComponent sous un package com.tutorialspoint.stateless comme expliqué dans le chapitre EJB - Créer une application . Vous pouvez également utiliser le projet créé dans le chapitre EJB - Persistance en tant que tel pour ce chapitre pour ajouter divers rappels à EJB.

2

Créez LibrarySessionBean.java et LibrarySessionBeanRemote comme expliqué dans le chapitre EJB - Créer une application . Gardez le reste des fichiers inchangé.

3

Utilisez les Beans créés dans le chapitre EJB - Persistence . Ajoutez des méthodes de rappel comme indiqué ci-dessous. Gardez le reste des fichiers inchangé.

4

Créez une classe java BookCallbackListener sous le package com.tutorialspoint.callback . Cette classe démontre la séparation des méthodes de rappel.

5

Nettoyez et créez l'application pour vous assurer que la logique métier fonctionne conformément aux exigences.

6

Enfin, déployez l'application sous forme de fichier jar sur JBoss Application Server. Le serveur d'applications JBoss démarrera automatiquement s'il n'est pas encore démarré.

sept

Créez maintenant le client EJB, une application basée sur la console de la même manière que celle expliquée dans le chapitre EJB - Créer une application sous la rubriqueCreate Client to access EJB.

EJBComponent (module EJB)

BookCallbackListener.java

package com.tutorialspoint.callback;

import javax.persistence.PrePersist;
import javax.persistence.PostLoad;
import javax.persistence.PostPersist;
import javax.persistence.PostRemove;
import javax.persistence.PostUpdate;
import javax.persistence.PreRemove;
import javax.persistence.PreUpdate;

import com.tutorialspoint.entity.Book;

public class BookCallbackListener {
    
   @PrePersist
   public void prePersist(Book book) {
      System.out.println("BookCallbackListener.prePersist:" 
         + "Book to be created with book id: "+book.getId());
   }

   @PostPersist
   public void postPersist(Object book) {
      System.out.println("BookCallbackListener.postPersist::"
         + "Book created with book id: "+((Book)book).getId());
   }

   @PreRemove
   public void preRemove(Book book) {
      System.out.println("BookCallbackListener.preRemove:"
         + " About to delete Book: " + book.getId());
   }

   @PostRemove
   public void postRemove(Book book) {
      System.out.println("BookCallbackListener.postRemove::"
         + " Deleted Book: " + book.getId());
   }

   @PreUpdate
   public void preUpdate(Book book) {
      System.out.println("BookCallbackListener.preUpdate::"
         + " About to update Book: " + book.getId());
   }

   @PostUpdate
   public void postUpdate(Book book) {
      System.out.println("BookCallbackListener.postUpdate::"
         + " Updated Book: " + book.getId());
   }

   @PostLoad
   public void postLoad(Book book) {
      System.out.println("BookCallbackListener.postLoad::"
         + " Loaded Book: " + book.getId());
   }
}

Book.java

package com.tutorialspoint.entity;
 
import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
 
@Entity
@Table(name="books")
public class Book implements Serializable{
    
   private int id;
   private String name;
 
   public Book() {        
   }
 
   @Id
   @GeneratedValue(strategy= GenerationType.IDENTITY)
   @Column(name="id")
   public int getId() {
      return id;
   }
 
   public void setId(int id) {
      this.id = id;
   }
 
   public String getName() {
      return name;
   }
 
   public void setName(String name) {
      this.name = name;
   }    
}

LibraryStatefulSessionBean.java

package com.tutorialspoint.stateful;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import javax.ejb.PostActivate;
import javax.ejb.PrePassivate;
import javax.ejb.Stateful;

@Stateful
public class LibraryStatefulSessionBean 
   implements LibraryStatefulSessionBeanRemote {
   List<String> bookShelf;    

   public LibraryStatefulSessionBean() {
      bookShelf = new ArrayList<String>();
   }

   public void addBook(String bookName) {
      bookShelf.add(bookName);
   }    

   public List<String> getBooks() {
      return bookShelf;
   }

   @PostConstruct
   public void postConstruct() {
      System.out.println("LibraryStatefulSessionBean.postConstruct::"
         + " bean created.");
   }

   @PreDestroy
   public void preDestroy() {
      System.out.println("LibraryStatefulSessionBean.preDestroy:"
         + " bean removed.");
   }

   @PostActivate
   public void postActivate() {
      System.out.println("LibraryStatefulSessionBean.postActivate:"
         + " bean activated.");
   }

   @PrePassivate
   public void prePassivate() {
      System.out.println("LibraryStatefulSessionBean.prePassivate:"
         + " bean passivated.");
   }    
}

LibraryStatefulSessionBeanRemote.java

package com.tutorialspoint.stateful;

import java.util.List;
import javax.ejb.Remote;

@Remote
public interface LibraryStatefulSessionBeanRemote {
   void addBook(String bookName);
   List getBooks();
}

LibraryPersistentBean.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
public class LibraryPersistentBean 
   implements LibraryPersistentBeanRemote {
    
   public LibraryPersistentBean() {}

   @PersistenceContext(unitName="EntityEjbPU")
   private EntityManager entityManager;         

   public void addBook(Book book) {
      entityManager.persist(book);
   }    

   public List<Book> getBooks() {     
      return entityManager.createQuery("From Book")
         .getResultList();
   }

   @PostConstruct
   public void postConstruct() {
      System.out.println("postConstruct:: LibraryPersistentBean session bean"
         + " created with entity Manager object: ");
   }

   @PreDestroy
   public void preDestroy() {
      System.out.println("preDestroy: LibraryPersistentBean session"
      + " bean is removed ");
   }
}

LibraryPersistentBeanRemote.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Remote;

@Remote
public interface LibraryPersistentBeanRemote {

   void addBook(Book bookName);

   List<Book> getBooks();
    
}
  • Dès que vous déployez le projet EjbComponent sur JBOSS, notez le journal jboss.

  • JBoss a créé automatiquement une entrée JNDI pour notre bean session - LibraryPersistentBean/remote.

  • Nous utiliserons cette chaîne de recherche pour obtenir un objet métier distant de type - com.tutorialspoint.stateless.LibraryPersistentBeanRemote

Sortie du journal du serveur d'applications JBoss

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

EJBTester (client 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
  • Ces propriétés sont utilisées pour initialiser l'objet InitialContext du service de nommage java.

  • L'objet InitialContext sera utilisé pour rechercher un bean session sans état.

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.testEntityEjb();
   }
   
   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 testEntityEjb() {    
      try {
      int choice = 1; 

      LibraryPersistentBeanRemote libraryBean = 
      (LibraryPersistentBeanRemote)
      ctx.lookup("LibraryPersistentBean/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++;
      }           

      } 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 effectue les tâches suivantes -

  • Chargez les propriétés de jndi.properties et initialisez l'objet InitialContext.

  • Dans la méthode testStatelessEjb (), la recherche jndi est effectuée avec le nom - "LibrarySessionBean / remote" pour obtenir l'objet métier distant (EJB sans état).

  • Ensuite, l'utilisateur voit une interface utilisateur de magasin de bibliothèque et il / elle est invité à entrer un choix.

  • Si l'utilisateur entre 1, le système demande le nom du livre et enregistre le livre à l'aide de la méthode addBook () du bean session sans état. Session Bean stocke le livre dans la base de données.

  • Si l'utilisateur entre 2, le système récupère les livres en utilisant la méthode getBooks () du bean session sans état et se ferme.

Exécuter le client pour accéder à EJB

Recherchez EJBTester.java dans l'explorateur de projet. Faites un clic droit sur la classe EJBTester et sélectionnezrun file.

Vérifiez la sortie suivante dans la console 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
BUILD SUCCESSFUL (total time: 13 seconds)

Sortie du journal du serveur d'applications JBoss

Vous pouvez trouver les entrées de rappel suivantes dans le journal JBoss

14:08:34,293 INFO  [STDOUT] postConstruct:: LibraryPersistentBean session bean created with entity Manager object
...
16:39:09,484 INFO  [STDOUT] BookCallbackListener.prePersist:: Book to be created with book id: 0
16:39:09,531 INFO  [STDOUT] BookCallbackListener.postPersist:: Book created with book id: 1
16:39:09,900 INFO  [STDOUT] BookCallbackListener.postLoad:: Loaded Book: 1
...