@Stateless
public class BookEJB {
··@PersistenceContext(unitName = "chapter07PU")
··private EntityManager em;
··public Book findBookById(Long id) {
····return em.find(Book.class, id);
··}
··public Book createBook(Book book) {
····em.persist(book);
····return book;
··}
}
Предыдущие версии J2EE вынуждали разработчиков создавать ряд артефактов для того, чтобы сгенерировать тот или иной сессионный EJB-компонент: локальный либо удаленный интерфейс (или и тот и другой), локальный домашний либо удаленный домашний интерфейс (или и тот и другой) и дескриптор развертывания. Java EE 5 и EJB 3.0 существенно упростили модель до такой степени, что стало достаточно лишь одного класса и одного или нескольких бизнес-интерфейсов, и вам не потребуется какая-либо XML-конфигурация. Как показано в листинге 7.1, с выходом EJB 3.1 классу даже не нужно реализовывать какой-либо интерфейс. Мы используем только одну аннотацию для того, чтобы превратить Java-класс в транзакционный и безопасный компонент — @Stateless. Затем, применяя менеджер сущностей (как можно было видеть в предыдущих главах), BookEJB создает и извлекает экземпляры Book из базы данных простым, но все же эффективным способом.
Анатомия EJB-компонента
В листинге 7.1 показана самая простая модель программирования для сессионных EJB-компонентов — аннотированный Java-объект без интерфейса. Однако, в зависимости от ваших нужд, сессионные EJB-компоненты могут обеспечить намного более богатую модель, позволив вам выполнять удаленные вызовы, внедрение зависимостей или асинхронные вызовы. EJB-компонент состоит из таких элементов, как:
•
•
Как показано на рис. 7.2, клиентское приложение может получить доступ к сессионному EJB-компоненту посредством одного из его интерфейсов (локального или удаленного) либо напрямую, вызвав сам класс EJB-компонента.
Рис. 7.2. Класс EJB-компонента обладает бизнес-интерфейсами нескольких типов
Класс EJB-компонента
Класс сессионного EJB-компонента — это любой Java-класс, который реализует бизнес-логику. Требования для разработки класса сессионного EJB-компонента таковы:
• класс должен быть снабжен аннотацией @Stateless, @Stateful, @Singleton или XML-эквивалентом в дескрипторе развертывания;
• он должен реализовывать методы своих интерфейсов при наличии таковых;
• класс должен быть определен как public и не должен быть final или abstract;
• класс должен располагать конструктором public без аргументов, который контейнер будет использовать для создания экземпляров;
• класс не должен определять метод finalize();
• имена бизнес-методов не должны начинаться с ejb, при этом они не могут быть final или static;
• аргумент и возвращаемое значение удаленного метода должны относиться к допустимым типам RMI.
Удаленные и локальные представления, а также представление без интерфейса