Компонентный подход в программировании

Дескрипторы развертывания компонентов EJB


Помимо декларации интерфейсов и классов компонентов, для построения EJB-компонента необходимо написать дескриптор развертывания — XML-файл в специальном формате, определяющий набор компонентов приложения и их основные свойства.

Чаще всего дескрипторы развертывания не пишут вручную, их готовят с помощью специализированных инструментов для развертывания J2EE-приложений или сред разработки (например, такими возможностями обладает среда NetBeans 4.0 [3]). Здесь мы опишем только часть содержимого дескрипторов развертывания. Полное описание используемых в них тегов и их назначения см. в [2].

Дескриптор развертывания упаковывается вместе с байт-кодом классов компонентов приложения в JAR-архив. При развертывании такой архив помещают в выделенную директорию, в которой сервером J2EE ищет развертываемые приложения. После этого сервер сам осуществляет запуск приложения и поиск кода компонентов, необходимых для обработки поступающих запросов, на основании информации, предоставленной дескриптором.

Заголовок дескриптора развертывания для набора EJB-компонентов версии 2.1 выглядит следующим образом.

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" http://java.sun.com/j2ee/dtds/ejb-jar_2_1.dtd">

Дескриптор развертывания содержит следующие теги.

  • <ejb-jar>

    Обязательный элемент.

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

  • <enterprise-beans>

    Обязательный элемент, должен появиться внутри <ejb-jar> ровно один раз.

    Содержит набор описаний отдельных EJB-компонентов в виде элементов <entity>, <session>, <message-driven>.

  • <entity> и <session>

    Эти теги вложены в тег <enterprise-beans> и служат для описания, соответственно, компонентов данных и сеансовых компонентов. Они могут содержать следующие вложенные теги.

    • <ejb-name>

      Требуется ровно один.

      Задает имя компонента.


    • <home>

      Необязателен, начиная с EJB 2.0. В EJB 1.1 требуется ровно один.

      Указывает полное имя удаленного исходного интерфейса.

    • <remote>



      Необязателен, начиная с EJB 2.0. В EJB 1.1 требуется ровно один.

      Указывает полное имя удаленного интерфейса.

    • <local-home>

      Необязателен.

      Указывает полное имя локального исходного интерфейса.

    • <local>

      Необязателен.

      Указывает полное имя локального интерфейса.

    • <ejb-class>

      Требуется ровно один.

      Указывает полное имя класса компонента.

    • <primkey-field>

      Необязателен, используется в описании компонентов данных.

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

    • <prim-key-class>

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

      Указывает имя класса первичного ключа. Можно отложить точное определение класса первичного ключа до развертывания, тогда в этом поле указывается java.lang.Object.

    • <persistence-type>

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

      Имеет значения Bean или Container, в зависимости от того, управляется ли синхронизация компонента с базой данных самим компонентом или контейнером.

    • <cmp-version>

      Необязателен.

      Указывает версию спецификаций EJB, в соответствии с которой разработан компонент, что определяет способ управления этим компонентом. Может иметь значения 2.x и 1.x.

    • <abstract-schema-name>

      Необязателен.

      Задает уникальный идентификатор компонента для использования в запросах на языке EJB QL, который используется для описания запросов к схеме данных при реализации компонента данных, самостоятельно управляющего связью с СУБД.

    • <cmp-field>

      Один или более, используется в описании компонентов данных.

      Каждый такой элемент описывает одно поле данных, синхронизация которого с СУБД управляется EJB-контейнером. Он может содержать тег <description> с описанием поля и должен содержать тег <field-name> с именем поля.


      В EJB 2.0 это имя совпадает с именем абстрактного свойства (для которого в классе компонента декларированы методы getName() и setName()), а в EJB 1.1 — с именем одного из полей класса компонента.

    • <security-role-ref>

      Один или более, необязателен.

      Указывает роли, используемые данным компонентом. Они при работе приложения служат для авторизации доступа — сопоставляются с ролями, которым разрешен доступ к тому или иному методу.

      Может содержать тег <description> (необязателен) и теги <role-name> (обязателен), <role-link> (необязателен, служит для сопоставления указанного имени роли с логической ролью, описанной в <security-role> раздела <assembly-descriptor>).

    • <security-identity>

      Необязателен.

      Определяет, какую логическую роль будет играть данный компонент при обращениях к другим компонентам. Для этого может быть использован вложенный тег <run-as><role-name>…</role-name></run-as> для указания имени конкретной логической роли, или <use-caller-identity/> для указания того, что нужно использовать роль вызывающего клиента.

    • <session-type>

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

      Имеет значения Stateful или Stateless, в зависимости от того, использует ли данный компонент состояние сеанса.

    • <transaction-type>

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

      Имеет значения Container или Bean, в зависимости от того, управляет ли транзакциями данного компонента контейнер или он сам. В первом случае соответствующие транзакции должны быть описаны в разделе <assembly-descriptor> (см. далее).

    • <query>

      Один или более, необязателен.

      Используется для описания запросов, с чьей помощью реализуются некоторые методы компонентов данных, которые сами управляют связью с базой данных. Запросы описываются на языке EJB QL [X] и привязываются к методам компонента с помощью тегов <query-method>. Сам код запроса описывается внутри элемента CDATA во вложенном теге <ejb-ql>.



      Например

      <query> <query-method> <method-name>findByName</method-name> <method-params> <method-param>java.lang.String</method-param> </method-params> </query-method> <ejb-ql> <!CDATA[ SELECT OBJECT(c) FROM Client c WHERE c.name = ?1 ]] </ejb-ql> </query>
    • <relationships>

      Необязателен. Вложен в <ejb-jar>.

      Описывает набор отношений между компонентами, которые соответствуют связям в схеме базы данных и автоматически поддерживаются контейнером. Каждое отношение описывается с помощью вложенного тега <ejb-relation>.

    • <ejb-relation>

      Описывает одно отношение и может иметь следующие элементы.

      • <ejb-relation-name>

        Необязателен, только один. Задает имя отношения.

      • <ejb-relationship-role>

        Обязательно два. Описывает одну роль в рамах отношения. В описании роли должны присутствовать следующие данные.

      • Имя роли — во вложенном теге <ejb-relationship-role-name>.
      • Множественность — сколько экземпляров компонента могут играть такую роль в рамках данного отношения с одним экземпляром в другой роли. Описывается в теге <multiplicity> и может иметь значения One или Many.
      • Имя компонента, экземпляры которого играют данную роль в этом отношении. Определяется в теге <relationship-role-source> внутри тега <ejb-name> в виде имени, которое присвоено компоненту в рамках данного дескриптора.
      • Имя поля, которое хранит ссылку или коллекцию ссылок, поддерживающие это отношение в рамках экземпляра компонента. Определяется в теге <cmr-field>, во вложенном теге <cmr-field-name>, и для него в классе компонента должно быть определено абстрактное свойство с тем же именем.
  • <assembly-descriptor>

    Этот обязательный тег внутри <ejb-jar> содержит дополнительные указания для сборки компонентов, в частности следующие.

    • <container-transaction>

      Один или более, необязателен.

      Содержит необязательный элемент <description>, а также приведенные ниже.

      Для компонента данных должно быть по одному такому элементу на каждый метод удаленного интерфейсов.


      Сеансовые компоненты, транзакциями которых управляет EJB-контейнер, также должны подчиняться этому правилу.

      • <method>

        Один или более.

        Содержит тег <ejb-name>, указывающий имя компонента, и <method-name>, указывающий имя метода или знак *, который обозначает применение указанного атрибута ко всем методам.

        Может также включать элементы <description>, <method-params> и <method-intf>, который может иметь значения Remote, Home, Local, Local-Home, в зависимости от того, в каком интерфейсе этот метод декларирован — для поддержки возможности декларировать методы с одним именем и набором параметром в разных интерфейсах.

      • <trans-attribute>

        Ровно один.

        Определяет атрибут транзакции, управляющий политикой включения в транзакции или создания новых транзакций.

        Для компонентов данных атрибуты транзакции должны быть определены для всех методов удаленного интерфейса и методов, декларированных в исходном интерфейсе, для сеансовых компонентов — для всех методов удаленного интерфейса.

        Может иметь значения NotSupported, Supports, Required, RequiresNew, Mandatory, Never. Об их смысле рассказывалось в предыдущей лекции.

    • <security-role>

      Один или более, необязателен.

      Определяет роли, служащие для контроля доступа к методам компонентов. В таком элементе должен содержаться тег <role-name>, задающий имя роли.

    • <method-permission>

      Один или более, необязателен.

      Указывает правила доступа ролей, определенных в тегах <security-role>, к методам компонентов.

      Содержит необязательный тег <description>, один или несколько тегов <role-name> и один или несколько тегов <method> (см. выше), кроме того, в нем может присутствовать тег <unchecked/>, который обозначает отсутствие проверки прав доступа во время работы, даже если они описаны.

      Каждый тег <method> содержит тег <ejb-name>, указывающий имя компонента, и <method-name>, указывающий имя метода или знак *, который обозначает применение указанного атрибута ко всем методам.

    • <exclude-list>

      Необязателен.

      Содержит один или несколько тегов <method> (см. выше), определяющих методы, которые не должны вызываться при работе приложения. Каждый вызов такого метода создает исключительную ситуацию.




Содержание раздела