![]() |
|
||
|
|
|
Enterprise JavaBeans. Часть 3(Гопалан Суреш Рай) Компоненты EJB В предыдущем разделе вы познакомились с базовой моделью EJB. Теперь пора более детально рассмотреть наиболее существенные компоненты архитектуры EJB. Рисунок 4 даёт наглядное представление о поведении компонентов во время выполнения.
Рисунок 4: Основные компоненты архитектуры EJB Home-интерфейс и Home-объект Когда у клиента EJB возникает потребность воспользоваться услугами EJB, он с помощью home-интерфейса создаёт EJB. Клиент использует один из методов create(), которые определяет home-интерфейс. Реализация home-интерфейса осуществляется с помощью объекта, называющегося home-объектом. Экземпляр такого home-объекта создаётся на сервере и в качестве factory (построителя) предоставляется клиенту для создания бина. Поиск Home-объекта Клиент EJB определяет местонахождение home-объекта с помощью JNDI, так как ссылка на этот home-объект помещается в службе имён (naming service). Соответствующее местоположение и имя factory-класса для контекста JNDI предоставляется клиенту изначально. Кроме знания места и имени класса, клиент должен иметь представление о том, как найти этот home-объект в структуре дерева имён (naming tree). Когда специалист по внедрению EJB устанавливает и запускает компонент EJB на сервере EJB, он или она должны указывать конкретное место расположения на дереве имён типа "cup/chap8/Account". Затем клиент EJB должен получить это полное имя для установления местонахождения, чтобы получить ссылку на home-объект "Account". Кусок кода, с помощью которого клиент создаёт бин, используя home-объект, будет выглядеть приблизительно так, как это показано в Примере 1: // get the JNDI naming context Пример 1: Клиентский код для создания бина EJB Определение Home-интерфейса Сам home-объект - это реализация интерфейса, который расширяет интерфейс javax.ejb.EJBHome. В нём есть необходимые для работы методы create(), find() и remove(), каждый из которых соответствует ejbCreate(), ejbFind() and ejbRemove(), с той же сигнатурой, что указана в реализации конкретного создаваемого бина. Также здесь представлены методы для получения метаданных этого бина. А интерфейс EJBHome определяется в спецификации так, как это показано в Примере 2:
public interface javax.ejb.EJBHome extends Remote {
public abstract void remove (Handle handle) throws RemoteException, RemoveException; public abstract void remove (Object primaryKey) throws RemoteException,RemoveException; public abstract EJBMetaData getEJBMetaData () throws RemoteException; } Пример 2: Определение интерфейса EJBHome Разработчику EJB нужно будет в своих бинах определить методы ejbCreate(). Кроме этого он также должен определить имеющиеся методы create(), соответствующие сигнатурам, указанным в home-интерфейсе бина EJB. Если разработчик кодирует entity-бин, то он или она вероятно должны будут определить также в home-интерфейсе методы для поиска, которые позволят клиенту определять местонахождение имеющихся entity-бинов в соответсвии с их идентификаторами. Описание обычного home-интерфейса для компонента EJB может выглядеть так, как показано в Примере 3: import javax.ejb.*; import java.rmi.*;
public interface AccountHome extends EJBHome {
Account create(int accountNo, String customer) throws CreateException, RemoteException; Account create(int accountNo, String customer, double startingBalance) throws CreateException, RemoteException; Account findByPrimaryKey(AccountPK accountNo) throws FinderException, RemoteException; } Пример 3: Определение интерфейса AccountHome Remote-интерфейс Разработчик EJB должен также создать remote-интерфейс, который описывает бизнес-методы бина, которыми сможет пользоваться клиент EJB. EJBObject получит код реализации, сгенерированный для этого интерфейса инструментальными средствами контейнера. Имена методов и их сигнатуры, указанные в remote-интерфейсе, должны в точности соответствовать именам и сигнатурам бизнес-методов, указанным в бине, в отличие от home-интерфейса, когда совпадают только сигнатуры методов, а их имена отличаются. Описание обычного remote-интерфейса для компонента EJB будет выглядеть так, как показано в примере 4: import javax.ejb.*; import java.rmi.*;
public interface Account extends EJBObject {
void credit (double amount) throws RemoteException; void debit (double amount) throws RemoteException; double getBalance () throws RemoteException; } Пример 4: Определение remote-интерфейса Account EJBObject EJBObject - это видимый в сети объект с собственной стуктурой и наполнением, действующий как proxy бина. Имеющийся у бина remote-интерфейс расширяет интерфейс javax.ejb.EJBObject, делая таким образом класс EJBObject специфическим для данного класса бина. Для каждого бина EJB существует стандартный класс EJBObject. Entity-бин и Session-бин Enterprise-бины представляют собой строительный материал, конструктивные элементы, которые могут использоваться как самостоятельно так и в сочетании с другими бинами в целях создания сложных, надёжных, многоуровневых тонко-клиентских приложений. Компонент EJB - это отрезок кода, имеющий поля и методы для реализации каждого модуля бизнес-логики. Они могут быть как постоянными так и непостоянными. Мы можем говорить о наличии двух видов enterprise-бинов: Entity-бины — компоненты, предназначенные для моделирования бизнес объектов. Session-бины — компоненты общего назначения для работы на серверной стороне. На Рисунке 5 приводится "вид сверху" на взаимодействие session-бинов и entity-бинов в среде EJB.
Рисунок 5: Типичная среда EJB, включающая entity и session-бины Прежде чем мы перейдём к обсуждению этих бинов, Вам необходимо понять концепцию активизации и перевода в пассивное состояние (activationи passivation). Перевод в пассивное состояние - это процесс, цель которого сохранить состояние бина в базе данных для последующего использования. Активизация - это процесс, в результате которого устанавливается состояние бина с помощью получения данных из перманентной базы данных. Entity-бины Еntity-бин представляет собой перманентные данные, хранящиеся в структуре домена, а также методы для обработки этих данных. Если быть ещё более точным, то entity-бин указывает путь к конкретным данным в модели домена. В контексте релятивных баз данных, для каждой строки таблицы существует свой отдельный бин. Эта концепция не нова, так построены все объектные базы данных. Каждый entity-бин определяется своим первичным ключом. Entity-бины создаются с помощью построителя объектов (object factory) - метода create(). Эти бины также либо сами перманентны, либо передают эту функцию своему контейнеру. Entity-бины всегда имеют какое-либо состояние, которое может быть зафиксировано и сохранено. С другой стороны, одним entity-бином могут пользоваться сразу несколько клиентов EJB одновременно. Срок действия бина ничем не ограничен, даже жизненным циклом виртуальной машины, в рамках которой он выполняется. Сбой виртуальной машины может только стать сигналом начала процедуры возврата в исходное состояние (rollback) текущей транзакции, но не сможет ни уничтожить сам бин, ни изменить ссылку, по которой к нему обращаются клиенты. Более того, клиент сможет обратиться к бину позднее, пользуясь той же ссылкой, так как она содержит уникальный для бина первичный ключ, позволяющий enterprise-бину или его контейнеру, перезагружать его состояние. Таким образом, entity-бинам не страшны системные сбои или отключения. Персистентность entity-бинов может быть двух видов: Персистентность, управляемая контейнером (Container-managedpersistence): В этом случае за сохранение состояния entity-бина отвечает контейнер EJB. Здесь реализация бина будет зависеть от источника данных. Все управляемые контейнером поля должны быть, тем не менее, указаны в описании установки и внедрения (deployment descriptor), чтобы контейнер осуществлял управление персистентностью автоматически. Персистентность, управляемая бином (Bean-managedpersistence): В этом же случае, сам бин отвечает за сохранность своего состояния, а контейнеру не нужно генерировать никакие обращения к базе данных. Следовательно, данная имплементация менее гибка чем предыдущая, так как требует, чтобы отвечающий за это код был частью кода бина. Итого: каждый entity-бин должен обладать следующими характеристиками: К еntity-бинам может обращаться одновременно большое количество пользователей. Entity-бины могут участвовать в транзакциях. Entity-бины представляют данные в структуре домена. Entity-бины перманентны. Они существуют до тех пор, пока существуют данные в структуре домена. Entity-бины не подвергаются влиянию системных сбоев. Клиент не теряет данные в результате сбоя или отключения сервера EJB. Entity-бины имеют постоянные объектные ссылки, которые содержат неизменяемый ключ данного бина. Session-бины Session-бин создаётся клиентом и в большинстве случаев существует только на протяжении срока выполнения одного сеанса. Он осуществляет операции от лица клиента. В число таких операций входят обращение к базе данных или выполнение числовых операций в соответствии с какими-либо формулами. Хотя эти бины могут быть транзактными, они не восстанавливаются после системного сбоя. Они могут не иметь состояния, или поддерживать диалоговое состоняние среди методов и транзакций. Контейнер управляет диалоговым состоянием session-бина, если тот должен быть удалён из памяти. Session-бин должен сам управлять своей персистентностью. Каждый session-бин обычно связан с одним клиентом EJB, отвечающим за его создание и удаление. Таким образом, session-бины являются "смертными" и не могут пережить виртуальную машину в которой они создаются. Бин может либо сохранять своё состояние, либо оставаться без него. И кроме того они "умирают" при системных сбоях или отключениях. Существует два вида session-бинов: Не имеющие состояния (Statelesssessionbeans ): Бины данного типа не имеют внутреннего состояния. Исходя из этого факта, такие бины не нуждаются в процедуре перевода в пассивное состояние и могут использоваться для обслуживания большого количества клиентов. Имеющие состояние (Statefulsessionbeans ): Бины этого типа имеют внутреннее состояние, а следовательно, должны подвергаться переводу в пассивное или активное состояние. Так как они могут сохранять своё состояние, они могут также называться persistentsessionbeans. Для каждого такого session-бина может существовать только один клиент EJB. Такие бины могут сохраняться и восстанавливаться в процессе клиентских сеансов. Метод getHandle() возвращает обработанный экземпляр объекта бина, который может использоваться для хранения состояния бина. В последствии для повторного получения бина из перманентной базы вызывается метод getEJBObject(), Характеристики, присущие session-бинам, можно сформулировать следующим образом: Session-бины работают от лица отдельных клиентов. Экземпляр такого бина является расширением клиента, который его создаёт. Session-бины могут хранить информацию о транзакциях. Session-бины могут обновлять данные в соответствующей базе данных. Session-бины относительно недолговечны. Жизненный цикл неимеющего состояния бина ограничен циклом его клиента. Session-бины могут погибать в результате сбоев сервера EJB. Чтобы продолжить вычисления, клиент должен устанавливать связь с новым объектом session-бина. Session-бины не представляют данных, которые должны сохраняться в базе данных. Каждый session-бин может читать и обновлять базу данных от лица клиента. Его поля могут содержать диалоговое состояние клиента. Это состояние описывает диалог, представленный специфической клиент/серверной парой. В процессе транзакции часть этой информации может сохраняться в кэше бина. Session-бины по сути являются закрытыми ресурсами, использующимися исключительно клиентами, которые их создали. По этой причине session-бин прячет свой идентификатор и остаётся анонимным, что совершенно отличается от природы entity-бина, который демонстрирует себя с помощью первичного ключа. В Таблице 2 приводятся основные различия между session-бинами и entity-бинами.
Таблица 2: Различия между Session и Entity-бинами |
| Справка | Условия | |
| В начало | Логин | Комментарий к колонке | Поиск | Почта |