IT • archiv

rus / eng | Логин | Комментарий к колонке | Печать | Почта | Клуб




Колонки


Enterprise JavaBeans. Часть 8

 
(Гопалан Суреш Рай)
Модель использования Session и Entity-бинов

Говоря в общем, session-бины занимаются вопросами коммуникации с клиентом, а entity-бины - внесением записей в модель домена.

  1. Еntity-бины используются в модели перманентных объектов (в качестве контейнеров JDBC, к примеру), обеспечивающих Вашему приложению объектно-ориентированный интерфейс к модели Ваших данных. Session-бины используются для создания логики приложения. Например, session-бины используются для моделирования уровня, который связан с Вашей объектной моделью, но обычно не обращается напрямую к Вашей базе данных. Таким образом, набор session-бинов обеспечивает весь необходимый для приложения функционал, при этом некоторые из них могут обращаться к объектной модели, выполненной на основе entity-бинов. Именно EJBObject, принадлежащий такому session-бину, будет связываться с кодом GUI (или сервлетом, или ещё чем-либо) для предварительной обработки данных. Помните, что entity-бины могут, тем не менее, иметь ещё и объектное поведение. Но как обычно, каких-либо строгих правил на счёт этого нет; всё будет зависеть от конкретного сценария.
  2. Session-бины используются исключительно как связующее средство с клиентом, обеспечивая надёжный фасад для разрабатываемой модели. А entity-бины следует использовать для обеспечения точности и целостности баз данных, а не столько для объектного представления данных. Затем для выполнения процесса работы с базами данных снова следует вернуться к session-бинам. Подобное разделение функций позволяет избежать трудностей, возникающих при работе с новыми/модифицированными процессами, поскольку облегчается процедура тестирования.
  3. Постарайтесь, чтобы entity-бины могли использоваться не только в этом конкретном приложении. Хотя создать такой многоразовый бин сложно, в последствии Вы или Ваша компания неоднократно убедитесь в том, что не зря потратили свои деньги и время.
  4. Врядли можно ожидать также, что и session-бинами можно будет воспользоваться в дальнейшем. Вместо этого проще их удалять и писать новые, пользуясь возможностями RAD (Rapid Application Development).
  5. Совершенствуйте entity-бины, так как они являются хорошей основой для моделирования бизнес-объектов, которые выполняют чётко опредённую функцию, используются большим количеством клиентов и могут использоваться достаточно долго. Они также могут нести в себе бизнес-логику, определяемую их функцией. Session-бины могут использовать везде, где для выполнения метода требуются услуги двух и более компонентов. Представляется разумной идея представлять системные интерфейсы в виде session-бинов.

Подведём итог:

  • Session-бины используются для определения логики приложения.
  • Session-бины выступают в качестве интерфейсов клиента.
  • Шансов воспользоваться session-бином повторно не много.
  • Session-бины используются для управления работой группы entity-бинов.

  • Entity-бины используются для создания модели перманентных объектов (для хранения кода JDBC).
  • Entity-бины служат для обеспечения точности и целостности баз данных.
  • Entity-бины должны использоваться неоднократно.
  • Entity-бины могут использоваться для создания бизнес-объектов с уникальными функциями, которые могут использоваться одновременно большим количеством клиентов.

Контейнер EJB

Контейнер - это набор классов, сгенерированных средсвом развертывания, которое управляет среди прочего персистентностью бина, транзактными свойствами и защитой данных. 

Функции, получаемые от контейнера

Контейнер EJB обеспечивает для компонентов EJB распределённую объектную инфраструктуру. EJB играет роль исходного объекта ORB, понимающего семантики CORBA/IDL или RMI/IDL. Передающий уровень IIOP должен уметь создавать транзакции OTS для CORBA.

Контейнер помогает паковать и разворачивать компоненты. Компоненты EJB пакуются в с помощью манифестов, JAR и описаний установки и применеия. Контейнер распаковывает JAR с компонентом и выполняет его в соответствии с описанием установки и применения.

Контейнеры EJB осуществляют декларативное управление транзакциями, позволяя Вам выбирать транзактные объекты. И хотя EJB поддерживает транзакции выстроенные вокруг JTS, Вашему приложению нет необходимости явно обращаться к JTS чтобы участвовать в распределённых транзакциях. Контейнер EJB может явно управлять началом, выполнением или отменой транзакции. Он может также начать транзакцию, если таковой ещё нет, и осуществить с помощью имеющихся сервисов JTS её выполнение. На стадии разработки (или выполенения) с помощью декларативных команд из описания установки и применения Вы определяете транзактные аттрибуты своего EJB. На Ваше усмотрение остаётся вопрос, должен ли компонент EJB управлять границами транзакции, пользуясь семантикой JTS.

Контейнеры EJB управляют всем жизненным циклом бина. Если Вы являетесь разработчиком бина, Вам нужно обеспечить наличие remote-интерфейса для своего EJB. Вы также должны указать factory-интерфейс ("строительный" интерфейс), расширяющий factory-объект javax.ejb.EJBHome. Этот интерфейс должен иметь один или более методов create(), по одному для каждого из способов, которыми Вы создаёте свой EJBObject. Производитель контейнера автоматически генерирует реализацию factory. Тем не менее, Ваш enterprise Bean должен реализовывать методejbCreate() для каждого из методов create(), указанных Вами в factory-интерфейсе. И на конец, Вы должны зарегистрировать своих "строителей" с помощью контейнера, чтобы клиенты могли создавать новые бины. Контейнер также имеет поисковый интерфейс, помогающий клиентам определять местоположение имеющихся entity-бинов.

В процессе управления жизненным циклом бина контейнер обращается к бину, когда он загружен в память (активизирован), а также тогда, когда тот выгружен из памяти (переведён в пассивное состояние). Ваш компонент затем может использовать эти обращения для управления собственным состоянием явно и привлекать или высвобождать системные ресурсы.

Контейнер EJB может с одинаковым успехом управлять как транзактным бином так и перманентным. Перманентные или entity-бины содержат в ссылках на свои объекты уникальные идентификаторы, указывающие на их состояние. Любой entity-бин управляет своей персистентностью посредством прямой реализации персистентной операции. Контейнер просто передаёт соответствующий ключ и приказывает ему загрузить своё состояние. Еntity-бин может также делегировать контейнеру право управлять его состоянием. Контейнер может делать это простой сериализацией состояния бина и хранением его в какой-либо перманентной базе. Более сложная операция предполагает разграничение полей персистентности бина на столбцы в RDBMS. Ещё контейнер может реализовать персистентность с помощью встроенного ODBMS. Более развитые контейнеры EJB могут загружать состояние бина из перманентной базы и затем сохранять его в границах транзакции.

Контейнеры EJB могут предоставлять метаданные о бинах, которые в них находятся. Например, контейнер может возвращать имя класса бина, с которым связан конкретный factory-интерфейс (EJBHome).

Контейнеры EJB автоматизируют управление некоторыми аспектами защиты данных бина. Разработчик EJB должен определить соответствующие роли для своего EJB в предназначенном для этого объекте SecurityDescriptor. Затем разработчик сериализует этот объект и кладёт в JAR своего бина. Контейнер EJB использует этот объект для выполнения контрольных проверок от имени EJB.

Взаимоотношения между контейнером EJB и сервером

Пока нет спецального интерфейса для соединения контейнера и сервера, поэтому на этом этапе пока невозможно выпускать самостоятельные независимые от сервера контейнеры. Компоненты EJB предназначены для того, чтобы использоваться в контейнере EJB; они не выполняются как самостоятельные классы. Причина кроется в том, что контейнер обеспечивает для бина логический интерфейс к внешнему миру; сервер обеспечивает имплементацию функциональности необходимой контейнеру (персистентность, транзакции, сведение, инстанциирование и т.п.). Идея заключается в том, что сервер и контейнер занимаются обеспечением базовых функций (транзакций, персистентности и т.п.), так что Вам остаётся только работать над бизнес-логикой. При работе над EJB Вам не нужно реализовывать свой собственный механизм персистентности или иметь дело с многонитевыми процессами. Использование EJB помогает вам избежать трудностей, связанных с построением распределённых систем. 

Создание настраиваемых контейнеров EJB

Спецификация EJB позволяет настраивать контейнер. Бины, которые используют настроенные контейнеры не могут использоваться в стандартном контейнере, хотя обратный процесс допустим (другими словами, обычные компоненты EJB могут запросто помещаться в настроенный контейнер). Так как сперцификация также не определяет условия взаимодействия контейнера и сервера, интерфейсы для такого взаимодействия пока являются специфическими для каждого отдельного сервера. Для создания своего стандартного контейнера Вам придётся работать в непосредственном контакте с каким-либо из производителей серверов.

И всё же для дальнейшего развития модели EJB и создания настраиваемого в соответствии с запросами конкретного предприятия контейнера можно привести достаточное количество причин. Первые три, что приходят на ум, приведены ниже:

  1. Расширение взаимодействия между контейнером и EJB для интеграции с устаревшими системами или включения функции, на данный момент не имеющейся у EJB. В качестве примера можно привести службу событий (event service).
  2. Отношение к устаревшим приложениям как гарантам персистентности. Взаимоотношения между контейнером и бином и контейнером и клиентом EJB не изменяются.
  3. Многоразовая реализация функций, используемых или предоставляемых контейнером EJB. Например, интеграция программного обеспечения предприятия требует того, чтобы и сервер использовал соответствующее обеспечение. И снова, ни каких изменений в рамках взаимоотношений между компонентами не происходит.

Если Вы хотите в полной мере воспользоваться преимуществами компонентной модели EJB, расширение возможностей взаимодействия EJB гораздо предпочтительнее написанию контейнеров с нуля. Теоретически, нет ничего страшного в том, что организации реализуют компонентные модели с различными интерфейсами или способами взаимодействия, это может сказаться только на значительном ограничении преимуществ, предоставляемых комонентными моделями, которыми может воспользоваться организация.

Взаимодействие между клиентом и контейнером EJB

Изготовитель EJB должен строго соблюдать наличие двух видов взаимодействия: клиентское взаимодействие и компонентное взаимодействие. Клиентское взаимодействие - это связь между клиентом EJB и контейнером EJB, и представляет собой то, как клиент видит данный enterprise bean. Оно служит для установления уникальных особенностей при помощи указания home-интерфейса и определения порядка работы мотодов классов. Интерфейс JNDI определяет, как найти и идентифицировать объекты EJB и контейнера. Для каждого EJB в контейнере имеется уникальный ключ. А home-интерфейс выступает в качестве основного описания того, как создать компоненты EJB разной формы в соответствии с разными методами create(), и как удалять эти компоненты с помощью метода remove().

Жизненный цикл сеанса между клиентом EJB и сервером состоит из двух частей:

  • Как клиент видит EJB
  • Как контейнер EJB и сервер помогают клиенту
На Рисунке 8 показаны классы, принимающие участие в типичном для EJB сценарии. Здесь же приводится последовательность диаграмм:

Рисунок 8: Классы, использующиеся в стандартном сценарии для EJB

.

Вид со стороны клиента приведен на Рисунке 9

Рисунок 9: Как клиент видит сеанс enterprise JavaBean

Начиная с левого верхнего угла рисунка, клиент вначале создаёт контекст для поиска нужного EJBObject с помощью сервера JNDI. После того как контекст образован, клиент с помощью home-интерфейса создаёт компонент EJB. Теперь клиент может вызвать имеющиеся в EJBObject методы. Когда все действия выполнены, клиент вызывает метод  remove(), так же через home-интерфейс, для прекращения сеанса.

Соответствующий код приводится в Примере 20:

import javax.naming.*;
public class EJBClient { public static void main (String[] argv) { // get the JNDI naming context
Context initialCtx = new InitialContext (); 
 // use the context to lookup the EJB Home interface
AccountHome home=(AccountHome)initialCtx.lookup("Account");  
// use the Home Interface to create a Session bean object
Account account = home.create (1234, "Athul", 1000225.28d);  
// invoke business methods
account.credit (1000001.55d);  
// remove the object
account.remove (); }}

Пример 20: Код клиента EJB для обращения к EJB

Взаимодействие между контейнером и компонентом EJB

Компонентное взаимодействие устанавливается между контейнером EJB и компонентом и определяет механизм оповещения (callback mechanism) экземпляра EJB для регулирования процесса управления состоянием. Это позволяет контейнеру информировать EJB о событиях его жизненного цикла.

Схема работы объекта EJB и контейнера в упрощённом виде показана на Рисунке 10. Как сервер EJB так и контейнер выполняют действия, невидимые для клиента. Определение сервером местоположения контейнера не входит в обязанности ни клиента ни программиста.

Рисунок 10: Схема работы контейнера и enterprise JavaBean

Клиент начинает новую сеанс, посылая команду create(). Затем контейнер с помощью вызова newInstance() создаёт новый enterprise bean и определяет с помощью setSessionContext() контекст, в котором этот бин должен выполняться. В число составляющих контекст элементов входят: информация о контейнере, окружении и назначении клиента. И наконец, он посылает команду ejbCreate(), в которой указаны исходные параметры, установленные клиентом. В результате, появляется новый бин, к методам которого теперь можно обращаться напрямую без посредничества контейнера.

В некоторых случаях контейнер может с помощью вызова ejbPassivate() переносить экземпляры EJB во вторичный кэш, где они будут храниться. Когда для очередного сеанса понадобится объект EJB, его можно будет вызвать снова с помощью ejbActivate().  Когда клиент завершает сеанс, он вызывает destroy(), который перехватывается контейнером. Контейнер в свою очередь вызывает ejbDestroy(), давая ему возможность удалить всё, что следует. 

Контейрер может делать гораздо больше, чем просто выполнять операции над объектами EJB. В тех случаях, когда параллельно существует несколько одновременно работающих сессионных объектов, контейнер следит за последовательностью и правильностью выполнения всех операций. Контейнер может выводить во вторичный кэш объекты, бездействующие долгое время. Это позволяет избегать перегрузки памяти, при этом не влияя на сеанс и состояние EJB. Контейнер также может учитывать количество входящих обращений, чтобы высчитывать, сколько ещё дополнительных сеансов может понадобиться в будущем, и распределять их по времени, экономя таким образом время на установление связей. 

Возможность кэшировать сессионный объект EJB отличается от кэширования перманентных объектов. При таком виде хранения все данные исчезают, как только выключается машина или удаляется контейнер. Это временный кэш, который существует только для поддержания работы программы, когда той необходимо обработать большое количество сессионных объектов. 

Контейнер справляется с обработкой сессионных объектов автоматически, не прибегая к помощи клиента или сервера. В каждом EJB есть специальный метод, описывающий, как активизировать (вызвать из кэша) или перевести в пассивное состояние (удалить в кэш) эти объекты. Когда вызывается  ejbPassivate(), компонент EJB с помощью API или другого подходящего для этого метода сериализуется и отправляется во вторичную память. Метод ejbActivate(), соответственно, выполняет обратную процедура.

Серверы EJB

Сервер приложений EJB предназначен исключительно для использования компонентов EJB. Это составляющий элемент архитектуры EJB - контейнеры EJB выполняются только в рамках сервера EJB. Говоря в общем, основными задачами сервера приложений являются повышение производительности и упрощение процесса разработки. Сервер приложений сочетает в себе возможности монитора транзакций и технологии распределённых объектов.

Наиболее важной характеристикой монитора транзакций и, соответственно, сервера приложений является грамотное распределение ресурсов. Сервер приложений сводит и обрабатывает обширные системные ресурсы типа сетевых обращений, процессов, нитей, памяти, связей с базами данных. Если Вы не хотите писать в своё приложение код для инициализации связей с базами данных, скопируйте их в буфер, а затем поместите их в нужное приложение. Если захотите, сервер сделает это за Вас.

EJB ещё больше упрощает работу сервера приложений. EJB автоматизирует сложные микропрограммные процессы типа транзакций, защиты данных, управления состоянием и персистентности.

Распределённым объектам всегда нужно знать, где искать друг друга, пользуясь службой имён, насколько надёжны объекты, к которым они обращаются, и как контролировать свой жизненный цикл. Функции типа службы имён, управления распределёнными транзакциями, механизма защиты, удалённого доступа, персистентности, кэширования ресурсов, хранения объектов и их параллельного выполнение и многие другие автоматически обрабатываются (являются функцией) сервером EJB. Кроме того, EJB также определяет некоторые коструктивные особенности и правила наименования.

Note

В предыдущем параграфе я ничего не говорил о хранении в кэше связей с базами данных. Хотя в спецификации EJB говориться о перемещении в кэш экземпляров объектов, там нет ни слова о связях.

Чтобы проследить за работой алгоритма управления этими экземплярами, нужно рассматривать экземпляры компонентов EJB как объекты, населяющие контейнер EJB. Когда запрос метода проходит от клиента, расположенного за пределами контейнера, к экземпляру компонента, он должен пройти через контейнер. Контейнер перехватывает метод до того, как тот доберётся до бина. Это даёт возможность контейнеру участвовать в доставке данного запроса. А одним из способов такого участия может быть внедрение алгоритма управления экземпляром компонента в процесс доставки.

Управление экземплярами должно обмануть клиента, который считает, что получает нужный ему объект среднего уровня, который ждёт получения очередного запроса от клиента. Но клиент даже не догадывается, существует ли на самом деле такой объект среднего уровня. Всё что знает клиент, так это то, что к тому моменту, когда метод дойдёт до контейнера, там должно быть что-то, что получит этот метод.

Слияние экземпляров и EJB

EJB применяет алгоритм хранения экземпляров под названием Instance Pooling (IP). В рамках этого алгоритма складируются не связи с базами данных, а сами экземпляры среднего уровня. После того как контейнер перехватывает метод и до того как доставляет его экземпляру бина, он не создаёт ещё один экземпляр для обработки запроса. Он использует один из уже имеющихся в кэше экземпляров. Когда экземпляр заканчивает обработку метода, контейнер не уничтожает его. Вместо этого, он отправляет его обратно в буфер.

Так как IP алгоритм не занимается постоянным созданием и уничтожением экземпляров компонентов, ему не нужно беспокоится о надёжности механизма создания и уничтожения связей с базами данных. Конечно, непосредственное создание экземпляра иногда бывает медленным, но это случается довольно редко.

Код IP выносит проблему создания и уничтожения связей за пределы логики выполнения в методы, выполняемые в момент, когда экземпляр впервые создаётся с помощью ejbActivate() и в конце удаляется с помощью ejbPassivate().

В EJB, экземпляры компонентов EJB среднего уровня могут сливаться в кэш. Поскольку компонент может какое-то время не работать, он не будет занимать системные ресурсы.

Как только поступает клиентский запрос, контейнер EJB достаёт уже имеющийся экземпляр компонента EJB. И как только запрос выполняется и посылается соответствующий ответ, компонент EJB возвращается обратно, без необходимости его удалять.

В принципе, вот что происходит на сервере, когда клиент запрашивает какие-либо функции компонента EJB, не имеющего состояния:

  1. Прочитать в базе состояние компонента.
  2. Выполнить бизнес-логику.
  3. Записать изменившееся состояние компонента, если таковое будет, обратно в базу.

В промежутках между вызовами, поступающими от клиента, EJB имеет какое-то состояние. Данный сценарий для "несостоятельного" бина будет верным тогда и только тогда, когда обращение к компоненту совпадает один к одному с границами транзакции. Вы можете легко осуществить и следующий сценарий:

  1. Прочитать в базе состояние компонента.
  2. Выполнить бизнес-логику.
  3. Вернуть данные клиенту.
  4. Клиент делает ещё 0-N обращений к бину, выполняя бизнес-логику и операции с базой данных.
  5. Записать изменившееся состояние компонента, если таковое будет, обратно в базу.

IP - концептуально простой мезанизм, имеющий малозависимый от алгоритма код. Фактически, бизнес-логика может обойтись даже без процедур чтения и записи, если алгоритм присоединяется к механизму транзактного оповещения.

Здесь Вам очень поможет спецификация JDBC 2.0, поскольку там можно найти встроенную поддержку для хранения в кэше связей с базами данных. Это значит, что любой продукт EJB может использовать JDBC 2.0 для доступа к релятивным базам данных, а буфер с хранящимися в нём связями может переноситься от одного продукта контейнера EJB к другому.

Реализия любого сервера EJB нуждается в системе выполнения, хотя в спецификации не оговаривается, какой именно. Ею может быть база данных, или какая-либо транзактная система, или что-либо на базе CORBA. В настоящее время большинство имплементаций серверов EJB основаны на JTS. Это, по большому счёту, способ интерпретации на Java работы Object Transaction Service (OTS) из CORBA, который занимается решением вопросов, встающих в процессе работы с распределёнными решениями масштаба предприятия. Будем надеяться, что со временем производители серверов смогут соеденить всё лучшее, что есть в одной и в другой технологиях, и создать сервер EJB на основе CORBA OTS/SSL, что даст нам прямой доступ к неисчислимым возможностям платформы CORBA через простые в применении API спецификации EJB.

Серверная инфраструктура

Сервер EJB обеспечивает организованную среду выполнения для контейнеров EJB. Среди наиболее важных функций, предоставляемых сервером EJB, нужно указать следующие:

Поддержка распределённых транзакций

Управление распределёнными транзакциями состоит из двух возможных уровней распределения: многичисленных пользователей приложения и многочисленных менеджеров ресурсов. Каждый уровень должен управляться по отдельности. JTS/OTS занимаются управлением пользователями приложения, в то время как XA и DTC работает с менеджерами ресурсов данных.

В распределённой объектной среде одна транзакция может связывать несколько разных объектов. Один объект начинает транзакцию и для выполнения необходимой операции вызывает какое-то количество методов другого объекта. Когда операция выполнена, транзакция успешно заканчивается и фиксирует свой результат. JTS/OTS определяет объект, называющийся транзактным контекстом (transaction context), который отслеживает всех участников транзакции. Когда транзакция успешно завершается, OTS передаёт транзактному координатору (TC) запрос о фиксации её результата для оповещения менеджеров ресурсов данных. OTS может предоставить свой собстенный TC или делегировать его функции либо координатору транзакций в базе данных, либо одному из распределённых координаторов (напрмер, Microsoft's DTC, Encina или Tuxedo). Большинство имплементаций EJB (WebLogic, Bluestone, Novera, Persistence, Oracle AS и Oracle8i) передают эту функцию базе данных и не поддерживают гетерогенные транзакции. На сегодняшний день только GemStone, Inprise, Secant, OrchidSoft и IBM WebSphere являются серверами EJB, которые имеют интегрированный сервис TC. Хотя компоненты EJB могут использоваться для имплементации нетранзактных систем, сама модель была разработана именно для распределённых транзакций. EJB требует, чтобы сервер приложений использовал систему управления распределёнными транзакциями, которая поддерживает двухфазный протокол фиксации транзакций. В основу транзакций EJB положен JTS. Отдельный enterprise bean не нуждается в специальном разграничительном коде для участия в распределённых транзакциях. Среда EJB автоматически осушествляет начало, выполнение или возврат в исходное состояние от лица бина. Методики выполнения транзакций в процессе работы могут регулироваться с помощью деклараций. При желании транзакции могут управляться клиентским приложением.

Управление транзакциями EJB

Каждая транзакция - это набор атомарных операций. Метод, который используется для выполнения транзакции, либо осуществляет транзакцию и фиксирует её результат, либо сообщает о невозвозможности осуществления транзакции. Также существует возможность отмены транзакции с помощью механизма возврата в исходное состояние (rollback mechanism).  Данные виды транзакций являются общепринятыми в мире баз данных, так как они помогают поддерживать хранящие в них данные в надлежащем порядке. Каждый выполняемый метод работает как самостоятельная транзакция. На Рисунке 11 показана процедура обработки транзакций.

Рисунок 11: Транзактный сеанс

Основные принципы программирования транзакций одинаковы, за исключением случаев, когда вызываются методы EJB. Рисунок 11 представляет собой последовательность диаграмм, соответствующую приведенному ниже коду , и показывает, что происходит, когда инициируется метод getStockPrice()

Приведенный в Примере 21 отрывок кода очень важен, поскольку он не только показывает, как написать транзактный код в Вашем бине, но и как подсоединиться к объекту удалённого сервера CORBA с помощью компонентов EJB.

import javax.ejb.*;
import javax.jts.UserTransaction;
import java.rmi.*;
import org.omg.CORBA.*;
import org.omg.CosNaming.*;
import Trader.*;
public class QuoteBean implements SessionBean { SessionContext ctx;
 public StockTrader trader;
  public double getStockPrice (String company)
   throws RemoteException {  // Code for Transactions in the enterprise bean
UserTransaction tx = ctx.getUserTransaction ();
 tx.begin (); 
 double value = trader.getStockPrice (company);
   if (value > 0)  tx.commit ();
     else  tx.rollback ();
       return value;
        } // Implement the methods mandated by the EJB Spec
public void ejbCreate () {}
 public void ejbActivate () {}
  public void ejbPassivate (){}
   public void ejbRemove () {}
    // Set the Session context and also get a reference to the
// Stock Trader CORBA server object running on a remote system.
public void setSessionContext (SessionContext ctx)  throws RemoteException {  this.ctx = ctx;
  try {  // Create and initialize the ORB
 ORB orb = ORB.init (args, null);
  // Get the root naming context
 org.omg.CORBA.Object objRef =
orb.resolve_initial_references ("NameService");
  NamingContext ncRef = NamingContextHelper.narrow (objRef);
  // Resolve the object reference in naming
 NameComponent nc = new NameComponent ("NASDAQ", "");  NameComponent path [] = {nc};
  trader = TraderHelper.narrow (ncRef.resolve (path));
    } catch (Exception e) {  e.printStackTrace ();
      } }}

Пример 21: Компонент QuoteBean работает как клиент CORBA

Прежде чем будет инициирован какой-либо метод, клиент должен сообщить о начале новой транзакции с помощью вызова  javax.jts.UserTransaction.begin().

Когда клиент вызывает метод, контейнер оповещает экземпляр EJB с помощьюafterBegin(). Бин начинает обрабатывать этот вызов.

В этом момент происходит одно из двух: клиент может запросить выполнение метода или передумать и вернуть всё на место. Если клиент решает выполнить метод, контейнер с помощьюсигнала beforeCompletion()оповещает EJB о том, что он готов принять информацию. Когда EJB заканчивает обработку поступившего вызова, и операция успешно завершается, EJB вначале посылает сообщение клиенту (если это сообщение будет), затем контейнер посылает сигнал afterCompletion() в виде True самому EJB. 

Если клиент отказывается от своего намерения, он может выполнить операцию возврата в исходное соотояние, сразу после того как начался вызов метода. Контейнер в свою очередь отправляет EJB сигнал setRollbackOnly(), чтобы тот отменил всё, что до этого сделал. Когда возвратная операция успешно завершается, контейнер посылает сигнал afterCompletion()в виде False , который напоминает бину, что тот должен инициализироваться повторно.

Методы инициализации и перевода в пассивное состояние, определяемые в интерфейсе для EJB и контейнера, работают так же, за исключением того, что экземпляр EJB не может быть переведён в пассивное состояние в процессе выполнения транзакции. Ещё стоит отметить тот факт, что не обязательно ограничивать транзакцию вызовом только одного метода. Внутри транзакции могут быть упакованы одновременно несколько вызовов. Это позволяет клиенту выполнять сложные операции, при этом имея возможность осуществлять операцию возврата в прежнее состояние, если вдруг где-то произойдёт сбой..

Многонитевые процессы и хранение ресурсов

Обычный enterprise bean не может использовать примитивные типы синхронизации нитей. Следовательно, слово "synchronized" никогда не появляется в коде компонентов EJB..

Спецификация EJB позволяет серверу переводить в пассивное состояние entity-бины в промежутках между выполнением методов, даже в процессе самой транзакции. Это сделано для того, чтобы сервер мог более эффективно управлять работой и хранением ресурсов. Когда контейнер переводит в пассивное состояние бин Х, он должен вначале вызвать ejbStore(), чтобы бин мог синхронизировать своё новое состояние с базой данных. Когда контейнер снова активизирует бин Х, он должен загрузить с помощью ejbLoad(), хранящееся в базе состояние. Загруженное состояние - это состояние, которое в большинстве случаев сохраняется транзакцией с помощью ejbStore(). При этом база данных делает все необходимые операции по синхронизации с остральными транзакциями.

Поскольку здесь задействованы проблемы обработки данных, спецификация EJB запрещает бину инициализировать новые нити. Чтобы система была контролируемой, сервер EJB должен сам управлять созданием новых нитей. Передача этой функции бину может повлечь серьёзные проблемы. Представьте себе такую ситуацию: два одновременно выполняющихся в одном и том же контексте процесса пытаются получить данные из базы. Если одна нить читает данные, которые в это время обновляются второй нитью, предсказать результат, полученный первой нитью, будет очень сложно, так как неизвестно, какие данные она прочтёт. Другой проблемой может быть невозможность для сервера обеспечить транзактную семантику X/Open, так как у него будет недостаточно информации о том, все ли процессы, участвующие в транзакции, завершили свою работу до того, как начался процесс фиксации результата транзакции.

Защита данных

Имплеменрации сервера EJB могут использовать во время обращения механизм аутентификации, который запускается клиентской программой во время доступа к серверу EJB. Данный механизм сообщает серверу ID клиента. Тем не менее, пока спецификация EJB не оговаривает, как именно должна выполняться эта процедура. Для получения идентификатора текущего клиента должен использоваться метод getCallerIdentity().

Данный механизм используется в работе EJB/CORBA. В этом случае клиент ORB добавляет свой идентификатор к каждому своему запросу.

Если два сервера EJB - Х и У - от двух разных производителей реализуют  EJB/CORBA, вполне возможно, что компоненты EJB, работающие в системе Х, смогут взаимодействовать с компонентами У, как если бы они были расположены в одной среде (и наоборот). Транзактный контекст между менеджерами транзакций на обойх сайтах будет передаваться через протокол OTS. То же самое будет относиться и к защите данных, хотя одной из систем придётся заниматься проблемой идентификации.

Такой принцип заложен и в процесс взаимодействия между клиентской и серверной системами. Если обе системы реализуют EJB/CORBA, они могут взаимодействовать даже в том случае, когда они выпущены разными производителями. Это означает, что если процесс выполнения клиента EJB/CORBA становится составным элементом JRE (среды выполнения Java), а JRE является составляющей браузера, тогда браузер может выполнять аплеты, которые являются клиентами серверов EJB, реализующих EJB/CORBA. Загружаемый аплет включает только специфические для клиентского приложения модули, а не специфические для сервера ORB, транзактный proxy или выполнение EJB. Такой принцип взаимодействия и стал главной мотивацией для реализации EJB/CORBA.

Совместимость CORBA/IIOP

В то время как спецификация EJB позволяет создателям серверов EJB использовать любой коммуникационный протокол для соединения клиента и сервераЮ документация EJB/CORBA четко определяет, как должно осуществляться данное соединение. Это позволяет производителям как серверов так и компонентов поддерживать взаимодействие между системными средствами и продуктами.

К примеру, у Java-клиентов есть на выбор два API   — хочешь Java RMI, хочешь Java IDL. Не Java-клиенты могут подсоединяться к серверномму компоненту через IIOP и подходящий язык IDL. Клиенты, использующие протол COM+ от Microsoft, тоже могут подключаться к серверным компонентам черех мост COM-CORBA. Интересным фактом здесь является то, что клиент компонента EJB сам может быть серверным компонентом в том случае, когда он является сервлетом. В этом случае даже клиент браузера может осуществить вызов EJB с помощью подсоединения к сервлету через HTTP.

Внедрение компонентов EJB

Компоненты EJB устанавливаются и выполняются как сериализованные объекты (*.ser files). Файл manifest используется для составления и хранения списка компонентов EJB. К каждому файлу .ser должен прилагаться файл опискания установки и применения (порядка внедрения компонента). Эти описания (deployment descriptor) являются сериализованными экземплярами класса и используются для передачи контейнеру информации о специфике и особенностях установки и выполнения бина. Лицо, занимающееся внедрением EJB, отвечает за наличие такого описания. Описание должно содержать сериализованный экземпляр EntityDescriptor или SessionDescriptor соответственно.

Стандартный пункт в EJB manifest выглядит следующим образом:

Name: ~gopalan/BankAccountDeployment.ser
Enterprise-Bean: True

Пример 22: Пункт в EJB manifest

Строка Name даёт ссылку на сериализованное описание. Строка Enterprise-Bean указывает на то, является ли указанный элемент компонентом EJB.

Перспективы

В настоящее время спецификация EJB существует как Version 1.0 и представляет собой прекрасную архитектурную основу для построения распределённых систем мастаба предприятия. И хотя авторы спецификации грамотно распределили роли, делегировав решение части задач нижнего уровня соответствующим разработчикам, некоторые разделы должны быть доработаны. Например, модель EJB для обработки преманентных объектов может быть усовершенствована. Также стоит подумать над стандартизацией взаимодействия между средствами разработки и системами, чтобы обеспечить унифицированный отладочный интерфейс для существующих сред разработки. Но наиболее существенным пунктом, требующим большей детализации, остаётся вопрос совместимости. Эта проблема имеет две стороны. Первая касается непосредственно вопроса "EJB-совместимого" сервера, вторая - гарантий того, что независимо от производителя все серверы смогут взаимодействовать друг с другом.

Резюме

Enterprise JavaBeans - это краеугольный камень того, что в терминологии Sun звучит как "Java 2 Enterprise Edition" (J2EE). Данная платформа состоит из набора спецификаций стандартов для создания масштабируемых, многофункциональных, транзактно-ориентированных, распределённых серверных приложений для предприятий. В свете этого, технология Enterprise JavaBeans является наиболее передовой технологией семейтва Java. Из данной статьи Вы узнали о том, что EJB упрощает процесс разработки бизнес-приложений в виде самостоятельных многоразовых серверных компонентов без необходимости вникать в детали самой технологии. Архитектура EJB - это гигинтский шаг в сторону облегчения процесса разработки, внедрения и управления большими приложениями масштаба предприятия.

TOC |




Справка | Условия Copyright © 1999 — 2010, IT • archiv.
В начало | Логин | Комментарий к колонке | Поиск | Почта