Обратный вызов — это механизм, с помощью которого жизненный цикл корпоративного компонента может быть перехвачен. В спецификации EJB 3.0 указаны обратные вызовы, для которых создаются методы обработчика обратных вызовов. EJB Container вызывает эти обратные вызовы. Мы можем определить методы обратного вызова в самом классе EJB или в отдельном классе. EJB 3.0 предоставил много аннотаций для обратных вызовов.
Ниже приведен список аннотаций обратного вызова для bean-компонента без сохранения состояния.
аннотирование | Описание |
---|---|
@PostConstruct | Вызывается, когда бин создается впервые. |
@PreDestroy | Вызывается, когда бин удаляется из пула бинов или уничтожается. |
Ниже приведен список аннотаций обратного вызова для компонента с состоянием —
аннотирование | Описание |
---|---|
@PostConstruct | Вызывается, когда бин создается впервые. |
@PreDestroy | Вызывается, когда бин удаляется из пула бинов или уничтожается. |
@PostActivate | Вызывается, когда бин загружается для использования. |
@PrePassivate | Вызывается, когда бин возвращается в пул бинов. |
Ниже приведен список аннотаций обратного вызова для бина, управляемого сообщениями.
аннотирование | Описание |
---|---|
@PostConstruct | Вызывается, когда бин создается впервые. |
@PreDestroy | Вызывается, когда бин удаляется из пула бинов или уничтожается. |
Ниже приведен список аннотаций обратного вызова для объекта управления данными:
аннотирование | Описание |
---|---|
@PrePersist | Вызывается, когда объект создается в базе данных. |
@PostPersist | Вызывается после создания объекта в базе данных. |
@PreRemove | Вызывается, когда объект удаляется из базы данных. |
@PostRemove | Вызывается после удаления объекта из базы данных. |
@PreUpdate | Вызывается до обновления объекта в базе данных. |
@PostLoad | Вызывается, когда запись извлекается из базы данных и загружается в объект. |
Пример приложения
Давайте создадим тестовое EJB-приложение для тестирования различных обратных вызовов в EJB.
шаг | Описание |
---|---|
1 |
Создайте проект с именем EjbComponent в пакете com.tutorialspoint.stateless, как описано в главе EJB — Создание приложения . Вы также можете использовать проект, созданный в главе EJB — Постоянство как таковой для этой главы, чтобы добавить различные обратные вызовы в EJB. |
2 |
Создайте LibrarySessionBean.java и LibrarySessionBeanRemote, как описано в главе EJB — Создание приложения . Сохраните остальные файлы без изменений. |
3 |
Используйте Бины, созданные в главе EJB — Постоянство . Добавьте методы обратного вызова, как показано ниже. Сохраните остальные файлы без изменений. |
4 |
Создайте Java-класс BookCallbackListener в пакете com.tutorialspoint.callback . Этот класс демонстрирует разделение методов обратного вызова. |
5 |
Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями. |
6 |
Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен. |
7 |
Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» . |
Создайте проект с именем EjbComponent в пакете com.tutorialspoint.stateless, как описано в главе EJB — Создание приложения . Вы также можете использовать проект, созданный в главе EJB — Постоянство как таковой для этой главы, чтобы добавить различные обратные вызовы в EJB.
Создайте LibrarySessionBean.java и LibrarySessionBeanRemote, как описано в главе EJB — Создание приложения . Сохраните остальные файлы без изменений.
Используйте Бины, созданные в главе EJB — Постоянство . Добавьте методы обратного вызова, как показано ниже. Сохраните остальные файлы без изменений.
Создайте Java-класс BookCallbackListener в пакете com.tutorialspoint.callback . Этот класс демонстрирует разделение методов обратного вызова.
Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.
Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.
Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» .
EJBComponent (модуль 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(); }
-
Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.
-
JBoss автоматически создал запись JNDI для нашего сессионного компонента — LibraryPersistentBean / remote .
-
Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.stateless.LibraryPersistentBeanRemote
Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.
JBoss автоматически создал запись JNDI для нашего сессионного компонента — LibraryPersistentBean / remote .
Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.stateless.LibraryPersistentBeanRemote
Вывод журнала сервера приложений 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 (клиент 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
-
Эти свойства используются для инициализации объекта InitialContext сервиса именования java.
-
Объект InitialContext будет использоваться для поиска сессионного компонента без сохранения состояния.
Эти свойства используются для инициализации объекта InitialContext сервиса именования java.
Объект InitialContext будет использоваться для поиска сессионного компонента без сохранения состояния.
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 выполняет следующие задачи —
-
Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.
-
В методе testStatelessEjb () поиск jndi выполняется с именем — «LibrarySessionBean / remote» для получения удаленного бизнес-объекта (EJB без сохранения состояния).
-
Затем пользователю показывается пользовательский интерфейс магазина библиотеки, и ему / ей предлагается ввести выбор.
-
Если пользователь вводит 1, система запрашивает имя книги и сохраняет книгу, используя метод addBook () сессионного компонента без сохранения состояния. Сессия Бин хранит книгу в базе данных.
-
Если пользователь вводит 2, система получает книги, используя метод getBooks () сессионного компонента без сохранения состояния, и завершает работу.
Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.
В методе testStatelessEjb () поиск jndi выполняется с именем — «LibrarySessionBean / remote» для получения удаленного бизнес-объекта (EJB без сохранения состояния).
Затем пользователю показывается пользовательский интерфейс магазина библиотеки, и ему / ей предлагается ввести выбор.
Если пользователь вводит 1, система запрашивает имя книги и сохраняет книгу, используя метод addBook () сессионного компонента без сохранения состояния. Сессия Бин хранит книгу в базе данных.
Если пользователь вводит 2, система получает книги, используя метод getBooks () сессионного компонента без сохранения состояния, и завершает работу.
Запустите клиент для доступа к EJB
Найдите EJBTester.java в проводнике проекта. Щелкните правой кнопкой мыши класс EJBTester и выберите файл запуска .
Проверьте следующий вывод в консоли 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)
Вывод журнала сервера приложений JBoss
Вы можете найти следующие записи обратного вызова в журнале JBoss