Учебники

EJB — Перехватчики

EJB 3.0 предоставляет спецификацию для перехвата вызовов бизнес-методов с использованием методов, аннотированных аннотацией @AroundInvoke. Метод перехватчика вызывается ejbContainer до его перехвата вызовом бизнес-метода. Ниже приведен пример сигнатуры метода перехватчика.

@AroundInvoke
public Object methodInterceptor(InvocationContext ctx) throws Exception {
   System.out.println("*** Intercepting call to LibraryBean method: " 
   + ctx.getMethod().getName());
   return ctx.proceed();
}

Методы перехватчика могут быть применены или связаны на трех уровнях.

  • По умолчанию — Перехватчик по умолчанию вызывается для каждого компонента в пределах развертывания. Перехватчик по умолчанию может применяться только через xml (ejb-jar.xml).

  • Класс — Перехватчик уровня класса вызывается для каждого метода компонента. Перехватчик уровня класса может применяться как с помощью аннотации через xml (ejb-jar.xml).

  • Метод — метод перехватчика уровня вызывается для определенного метода компонента. Перехватчик уровня метода может применяться как с помощью аннотации через xml (ejb-jar.xml).

По умолчанию — Перехватчик по умолчанию вызывается для каждого компонента в пределах развертывания. Перехватчик по умолчанию может применяться только через xml (ejb-jar.xml).

Класс — Перехватчик уровня класса вызывается для каждого метода компонента. Перехватчик уровня класса может применяться как с помощью аннотации через xml (ejb-jar.xml).

Метод — метод перехватчика уровня вызывается для определенного метода компонента. Перехватчик уровня метода может применяться как с помощью аннотации через xml (ejb-jar.xml).

Мы обсуждаем перехватчик уровня класса здесь.

Класс перехватчика

package com.tutorialspoint.interceptor;

import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;

public class BusinessInterceptor {
   @AroundInvoke
   public Object methodInterceptor(InvocationContext ctx) throws Exception {
      System.out.println("*** Intercepting call to LibraryBean method: " 
      + ctx.getMethod().getName());
      return ctx.proceed();
   }
}

Удаленный интерфейс

import javax.ejb.Remote;

@Remote
public interface LibraryBeanRemote {
   //add business method declarations
}

Перехваченный безгражданский EJB

@Interceptors ({BusinessInterceptor.class})
@Stateless
public class LibraryBean implements LibraryBeanRemote {
   //implement business method 
}

Пример приложения

Давайте создадим тестовое EJB-приложение для проверки перехваченного EJB без сохранения состояния.

шаг Описание
1

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.interceptor, как описано в главе EJB — Создание приложения . Вы также можете использовать проект, созданный в главе EJB — Создание приложения как таковой, для понимания перехваченных концепций EJB.

2

Создайте LibraryBean.java и LibraryBeanRemote в пакете com.tutorialspoint.interceptor, как описано в главе EJB — Создание приложения . Сохраните остальные файлы без изменений.

3

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

4

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

5

Теперь создайте клиент ejb, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» .

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.interceptor, как описано в главе EJB — Создание приложения . Вы также можете использовать проект, созданный в главе EJB — Создание приложения как таковой, для понимания перехваченных концепций EJB.

Создайте LibraryBean.java и LibraryBeanRemote в пакете com.tutorialspoint.interceptor, как описано в главе EJB — Создание приложения . Сохраните остальные файлы без изменений.

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

Теперь создайте клиент ejb, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» .

EJBComponent (модуль EJB)

LibraryBeanRemote.java

package com.tutorialspoint.interceptor;

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

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

LibraryBean.java

package com.tutorialspoint.interceptor;

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

import javax.ejb.Stateless;
import javax.interceptor.Interceptors;

@Interceptors ({BusinessInterceptor.class})
@Stateless
public class LibraryBean implements LibraryBeanRemote {
    
   List<String> bookShelf;    

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

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

   public List<String> getBooks() {
      return bookShelf;
   }   
}
  • Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.

  • JBoss автоматически создал запись JNDI для нашего сессионного компонента — LibraryBean / remote .

  • Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.interceptor.LibraryBeanRemote

Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.

JBoss автоматически создал запись JNDI для нашего сессионного компонента — LibraryBean / remote .

Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.interceptor.LibraryBeanRemote

Вывод журнала сервера приложений JBoss

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

   LibraryBean/remote - EJB3.x Default Remote Business Interface
   LibraryBean/remote-com.tutorialspoint.interceptor.LibraryBeanRemote - EJB3.x Remote Business Interface
...   

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.LibraryBeanRemote;

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.testInterceptedEjb();
   }
   
   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 testInterceptedEjb() {

      try {
         int choice = 1; 

         LibraryBeanRemote libraryBean =
         LibraryBeanRemote)ctx.lookup("LibraryBean/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.

  • В методе testInterceptedEjb () поиск jndi выполняется с именем — «LibraryBean / remote» для получения удаленного бизнес-объекта (EJB без сохранения состояния).

  • Затем пользователю показывается пользовательский интерфейс магазина библиотеки, и ему / ей предлагается ввести выбор.

  • Если пользователь вводит 1, система запрашивает имя книги и сохраняет книгу, используя метод addBook () сессионного компонента без сохранения состояния. Сессионный компонент хранит книгу в своей переменной экземпляра.

  • Если пользователь вводит 2, система получает книги с использованием метода getBooks () сессионного компонента без сохранения состояния и завершает работу.

Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

В методе testInterceptedEjb () поиск jndi выполняется с именем — «LibraryBean / 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.