EJB - Gọi lại

Gọi lại là một cơ chế mà vòng đời của hạt đậu doanh nghiệp có thể bị chặn lại. Đặc tả EJB 3.0 đã chỉ định các lệnh gọi lại mà các phương thức xử lý lệnh gọi lại được tạo. EJB Container gọi các lệnh gọi lại này. Chúng ta có thể định nghĩa các phương thức gọi lại trong chính lớp EJB hoặc trong một lớp riêng biệt. EJB 3.0 đã cung cấp nhiều chú thích cho các cuộc gọi lại.

Sau đây là danh sách các chú thích gọi lại cho bean không trạng thái -

Chú thích Sự miêu tả
@PostConstruct Được gọi khi một bean được tạo lần đầu tiên.
@PreDestroy Được gọi khi một hạt đậu được lấy ra khỏi vùng đậu hoặc bị phá hủy.

Sau đây là danh sách các chú thích gọi lại cho bean trạng thái:

Chú thích Sự miêu tả
@PostConstruct Được gọi khi một bean được tạo lần đầu tiên.
@PreDestroy Được gọi khi một hạt đậu được lấy ra khỏi vùng đậu hoặc bị phá hủy.
@PostActivate Được gọi khi một bean được tải để được sử dụng.
@PrePassivate Được gọi khi một hạt đậu được đưa trở lại hồ đậu.

Sau đây là danh sách các chú thích gọi lại cho bean hướng thông báo:

Chú thích Sự miêu tả
@PostConstruct Được gọi khi một bean được tạo lần đầu tiên.
@PreDestroy Được gọi khi một hạt đậu được lấy ra khỏi vùng đậu hoặc bị phá hủy.

Sau đây là danh sách các chú thích gọi lại cho thực thể bean:

Chú thích Sự miêu tả
@PrePersist Được gọi khi một thực thể được tạo trong cơ sở dữ liệu.
@PostPersist Được gọi sau khi một thực thể được tạo trong cơ sở dữ liệu.
@PreRemove Được gọi khi một thực thể bị xóa khỏi cơ sở dữ liệu.
@PostRemove Được gọi sau khi một thực thể bị xóa khỏi cơ sở dữ liệu.
@PreUpdate Được gọi trước khi một thực thể được cập nhật trong cơ sở dữ liệu.
@PostLoad Được gọi khi một bản ghi được tìm nạp từ cơ sở dữ liệu và được tải vào thực thể.

Ứng dụng mẫu

Hãy để chúng tôi tạo một ứng dụng EJB thử nghiệm để kiểm tra các lệnh gọi lại khác nhau trong EJB.

Bươc Sự miêu tả
1

Tạo một dự án với tên EjbComponent trong một gói com.tutorialspoint.stateless như được giải thích trong chương EJB - Tạo ứng dụng . Bạn cũng có thể sử dụng dự án được tạo trong chương EJB - Persistence như vậy cho chương này để thêm các lệnh gọi lại khác nhau cho EJB.

2

Tạo LibrarySessionBean.javaLibrarySessionBeanRemote như được giải thích trong chương EJB - Tạo ứng dụng . Giữ phần còn lại của các tệp không thay đổi.

3

Sử dụng Đậu đã tạo trong chương EJB - Sự bền bỉ . Thêm các phương thức gọi lại như hình dưới đây. Giữ phần còn lại của các tệp không thay đổi.

4

Tạo một lớp BookCallbackListener trong java trong gói com.tutorialspoint.callback . Lớp này sẽ thể hiện sự tách biệt của các phương thức gọi lại.

5

Làm sạch và xây dựng ứng dụng để đảm bảo logic nghiệp vụ đang hoạt động theo yêu cầu.

6

Cuối cùng, triển khai ứng dụng dưới dạng tệp jar trên Máy chủ ứng dụng JBoss. Máy chủ ứng dụng JBoss sẽ tự động khởi động nếu nó chưa được khởi động.

7

Bây giờ tạo ứng dụng khách EJB, một ứng dụng dựa trên bảng điều khiển theo cách tương tự như đã giải thích trong chương EJB - Tạo ứng dụng theo chủ đềCreate Client to access EJB.

EJBComponent (Mô-đun 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();
}

LibraryPersistsBean.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 ");
   }
}

LibraryPersistsBeanRemote.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();
    
}
  • Ngay sau khi bạn triển khai dự án EjbComponent trên JBOSS, hãy để ý nhật ký jboss.

  • JBoss đã tự động tạo một mục nhập JNDI cho bean phiên của chúng tôi - LibraryPersistentBean/remote.

  • Chúng tôi sẽ sử dụng chuỗi tra cứu này để lấy đối tượng nghiệp vụ từ xa thuộc loại - com.tutorialspoint.stateless.LibraryPersistentBeanRemote

Đầu ra nhật ký máy chủ ứng dụng 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 (Khách hàng 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
  • Các thuộc tính này được sử dụng để khởi tạo đối tượng InitialContext của dịch vụ đặt tên java.

  • Đối tượng InitialContext sẽ được sử dụng để tra cứu bean phiên không trạng thái.

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 thực hiện các tác vụ sau:

  • Tải các thuộc tính từ jndi.properties và khởi tạo đối tượng InitialContext.

  • Trong phương thức testStatelessEjb (), tra cứu jndi được thực hiện với tên - "LibrarySessionBean / remote" để lấy đối tượng nghiệp vụ từ xa (stateless EJB).

  • Sau đó, người dùng được hiển thị một cửa hàng thư viện Giao diện Người dùng và họ được yêu cầu nhập một lựa chọn.

  • Nếu người dùng nhập 1, hệ thống sẽ hỏi tên sách và lưu sách bằng phương thức addBook () phiên đậu không trạng thái. Phiên Bean đang lưu trữ sách trong cơ sở dữ liệu.

  • Nếu người dùng nhập 2, hệ thống sẽ truy xuất sách bằng phương thức getBooks () của phiên đậu không trạng thái và thoát.

Chạy ứng dụng khách để truy cập EJB

Định vị EJBTester.java trong trình khám phá dự án. Nhấp chuột phải vào lớp EJBTester và chọnrun file.

Xác minh kết quả sau trong bảng điều khiển 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)

Đầu ra nhật ký máy chủ ứng dụng JBoss

Bạn có thể tìm thấy các mục gọi lại sau trong nhật ký 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
...