Java Platform, Enterprise Edition (Java EE) 8
Учебник по Java EE

Назад Вперёд Содержание

Настройка Managed-бинов

Когда страница обращается к Managed-бину в первый раз, JavaServer Faces инициализирует его либо на основе аннотации @Named и области видимости в классе компонента, либо в соответствии с конфигурацией в файле конфигурации приложения. Для получения информации об использовании аннотаций для инициализации бинов см. Использование аннотаций для настройки Managed-бинов.

Вы можете использовать аннотации или файл конфигурации приложения для создания объектов Managed-бинов, которые используются в приложении JavaServer Faces, и для сохранения их в области видимости. Средство создания Managed-бина настраивается в файле конфигурации приложения с использованием XML-элементов managed-bean для определения каждого компонента. Этот файл обрабатывается во время запуска приложения. Для получения информации об использовании этого средства см. Использование элемента managed-bean.

Managed-бины, созданные в файле конфигурации приложения, управляются JavaServer Faces, но не CDI.

С помощью средства создания Managed-бина вы можете

  • Создавать бины в одном централизованном файле, который доступен всему приложению, а не создавайте условные объекты бинов по всему приложению

  • Настроить свойства бина без дополнительного кода

  • Настроить значения свойств компонента напрямую из файла конфигурации, чтобы он инициализировался этими значениями при его создании

  • Используя элементы value, установить свойство одного Managed-бина в качестве результата вычисления другого выражения значения

В этом разделе показано, как инициализировать компоненты с помощью средства создания Managed-бинов. Смотрите Запись свойств бинов и Пишем методы Managed-бинов для получения информации о программировании Managed-бинов.

Использование элемента managed-bean

Managed-бин инициируется в файле конфигурации приложения с помощью элемента managed-bean, который представляет объект класса компонента, который должен существовать в приложении. Во время выполнения JavaServer Faces обрабатывает элемент managed-bean. Если страница ссылается на компонент, а объект компонента не существует, JavaServer Faces создаёт объект компонента, как указано в конфигурации элемента.

Вот пример конфигурации Managed-бина из примера Duke's Bookstore:

<managed-bean eager="true">
    <managed-bean-name>Book201</managed-bean-name>
    <managed-bean-class>dukesbookstore.model.ImageArea</managed-bean-class>
    <managed-bean-scope>application</managed-bean-scope>
    <managed-property>
        <property-name>shape</property-name>
        <value>rect</value>
    </managed-property>
    <managed-property>
        <property-name>alt</property-name>
        <value>Duke</value>
    </managed-property>
    <managed-property>
        <property-name>coords</property-name>
        <value>67,23,212,268</value>
    </managed-property>
</managed-bean>

Элемент managed-bean-name определяет ключ, под которым компонент будет храниться в области видимости. Чтобы значение компонента отображалось на этот бин, атрибут value тега компонента должен соответствовать managed-bean-name до первой точки.

Элемент managed-bean-class определяет полное имя класса компонента JavaBeans, используемого для создания объекта бина.

Элемент managed-bean может содержать ноль или более элементов managed-property, каждый из которых соответствует свойству, определённому в классе бина. Эти элементы используются для инициализации значений свойств компонента. Если вы не хотите, чтобы конкретное свойство инициализировалось значением при создании объекта компонента, не включайте определение managed-property для него в файл конфигурации приложения.

Если элемент managed-bean не содержит других элементов managed-bean, он может содержать один элемент map-entries или list-entries. Элемент map-entries настраивает набор бинов, которые являются объектами Map. Элемент list-entries настраивает набор бинов, которые являются объектами List.

В следующем примере Managed-бин newsletters, представляющий компонент UISelectItems, настроен как ArrayList, представляющий набор объектов SelectItem. Каждый объект SelectItem в свою очередь настроен как Managed-бин со свойствами:

<managed-bean>
    <managed-bean-name>newsletters</managed-bean-name>
    <managed-bean-class>java.util.ArrayList</managed-bean-class>
    <managed-bean-scope>application</managed-bean-scope>
    <list-entries>
        <value-class>javax.faces.model.SelectItem</value-class>
        <value>#{newsletter0}</value>
        <value>#{newsletter1}</value>
        <value>#{newsletter2}</value>
        <value>#{newsletter3}</value>
    </list-entries>
</managed-bean>
<managed-bean>
    <managed-bean-name>newsletter0</managed-bean-name>
    <managed-bean-class>javax.faces.model.SelectItem</managed-bean-class>
    <managed-bean-scope>none</managed-bean-scope>
    <managed-property>
        <property-name>label</property-name>
        <value>Duke's Quarterly</value>
    </managed-property>
    <managed-property>
        <property-name>value</property-name>
        <value>200</value>
    </managed-property>
</managed-bean>
...

Этот подход может быть полезен для быстрого создания списков выбора элементов до того, как группа разработчиков успеет создать такие списки из базы данных. Обратите внимание, что каждый из отдельных бинов рассылки имеет параметр managed-bean-scope, равный none, поэтому они сами не будут помещены в какую-либо область.

Смотрите Инициализация свойств-массивов и списков для получения дополнительной информации о настройке коллекций в качестве бинов.

Для сопоставления со свойством, определённым элементом managed-property, необходимо убедиться, что часть выражения value тега компонента после точки совпадает с дочерним элементом managed-property — элементом property-name. В следующем разделе, Инициализация свойств с использованием элемента managed-property, более подробно объясняется, как использовать элемент managed-property. См. Инициализация свойств Managed-бина для примера инициализации свойства Managed-бина.

Инициализация свойств с использованием элемента managed-property

Элемент managed-property должен содержать элемент property-name, который должен соответствовать имени соответствующего свойства в бине. Элемент managed-property также должен содержать один элемент из набора, который определяет значение свойства. Это значение должно быть того же типа, который определён для свойства в соответствующем компоненте. Какой элемент вы используете для определения значения, зависит от типа свойства, определённого в бине. Таблица 16-1 перечисляет все элементы, которые используются для инициализации значения.

Таблица 16-1. Подэлементы элементов управляемого свойства, которые определяют значения свойств

Элемент

Какое значение определяет

list-entries

Определяет значения в списке

map-entries

Определяет значения отображения (Map)

null-value

Явно устанавливает для свойства значение null

value

Определяет одно значение, например выражение String, int или EL JavaServer Faces

Использование элемента managed-bean включает в себя пример инициализации свойства int (примитивного типа) с использованием дочернего элемента value. Вы также можете использовать дочерний элемент value для инициализации String и других объектных типов. В оставшейся части этого раздела описано, как использовать дочерний элемент value и другие дочерние элементы для инициализации свойств типов Java Enum, Map, array и Collection, а также параметры инициализации.

Ссылка на перечислимый тип Java (Enum)

Свойство Managed-бина также может иметь тип Java Enum (см. http://docs.oracle.com/javase/7/docs/api/java/lang/Enum.html). В этом случае дочерний элемент value элемента managed-property должен быть String, который соответствует одному из String константы Enum. Другими словами, String должно быть одним из допустимых значений, которые могут быть возвращены, если вы вызовете valueOf(Class, String) для enum, где Class — это класс Enum, а String — это содержимое дочернего элемента value. Для примера предположим, что свойство Managed-бина является следующим:

public enum Suit { Hearts, Spades, Diamonds, Clubs }
 ...
public Suit getSuit() { ... return Suit.Hearts; }

Предполагая, что вы хотите настроить это свойство в файле конфигурации приложения, соответствующий элемент managed-property выглядит следующим образом:

<managed-property>
    <property-name>Suit</property-name>
    <value>Hearts</value>
</managed-property>

Когда система сталкивается с этим свойством, она выполняет итерацию по каждому члену enum и вызывает toString() для каждого члена, пока не найдёт тот, который точно равен значению элемента value.

Ссылка на контекстный параметр инициализации

Ещё одна мощная функция средства создания Managed-бина — это возможность ссылаться на неявные объекты из свойства Managed-бина.

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

Вы можете сохранить код города в качестве начального значения по умолчанию в неявном объекте контекста initParam, добавив контекстный параметр в ваше веб-приложение и установив его значение в дескрипторе развёртывания. Например, чтобы задать контекстному параметру с именем defaultAreaCode значение 650, добавьте элемент context-param в дескриптор развёртывания и присвойте параметру имя defaultAreaCode и значение 650.

Затем напишите объявление managed-bean, которое настраивает свойство, ссылающееся на параметр:

<managed-bean>
    <managed-bean-name>customer</managed-bean-name>
        <managed-bean-class>CustomerBean</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
        <managed-property>
            <property-name>areaCode</property-name>
                <value>#{initParam.defaultAreaCode}</value>
            </managed-property>
            ...
</managed-bean>

Чтобы получить доступ к коду города во время отображения страницы, обратитесь к свойству из атрибута value тега компонента area:

<h:inputText id="area" value="#{customer.areaCode}"

Из других неявных объектов значения извлекаются аналогичным образом.

Инициализация свойств-отображений (Map)

Элемент map-entries используется для инициализации значений свойства компонента с типом Map, если элемент map-entries используется внутри элемента managed-property. Элемент map-entries содержит необязательный элемент key-class, необязательный элемент value-class и ноль или более map-entry.

Каждый из элементов map-entry должен содержать элемент key и элемент null-value или value. Вот пример, в котором используется элемент map-entries:

<managed-bean>
    ...
    <managed-property>
        <property-name>prices</property-name>
        <map-entries>
            <map-entry>
                <key>My Early Years: Growing Up on *7</key>
                <value>30.75</value>
            </map-entry>
            <map-entry>
                <key>Web Servers for Fun and Profit</key>
                <value>40.75</value>
            </map-entry>
        </map-entries>
    </managed-property>
</managed-bean>

Отображение, созданное этим тегом map-entries, содержит две записи. По умолчанию все ключи и значения преобразуются в String. Если вы хотите указать другой тип для ключей на карте, вставьте элемент key-class прямо внутри элемента map-entries:

<map-entries>
    <key-class>java.math.BigDecimal</key-class>
    ...
</map-entries>

Это объявление преобразует все ключи в java.math.BigDecimal. Конечно, вы должны убедиться, что ключи могут быть преобразованы в указанный тип. Ключ из примера в этом разделе не может быть преобразован в BigDecimal, потому что это String.

Если вы хотите указать другой тип для всех значений на карте, включите элемент value-class после элемента key-class:

<map-entries>
    <key-class>int</key-class>
    <value-class>java.math.BigDecimal</value-class>
    ...
</map-entries>

Обратите внимание, что этот тег устанавливает только тип всех подэлементов value.

Каждая map-entry в предыдущем примере включает в себя подэлемент value. Подэлемент value определяет одно значение, которое будет преобразовано в тип, указанный в бине.

Вместо использования элемента map-entries также можно назначить всю карту, используя элемент value, который задаёт выражение с типом карты.

Инициализация свойств-массивов и списков

Элемент list-entries используется для инициализации значений массива или свойства List. Каждое отдельное значение массива или List инициализируется с использованием элемента value или null-value. Вот пример:

<managed-bean>
    ...
    <managed-property>
        <property-name>books</property-name>
        <list-entries>
            <value-class>java.lang.String</value-class>
            <value>Web Servers for Fun and Profit</value>
            <value>#{myBooks.bookId[3]}</value>
            <null-value/>
        </list-entries>
    </managed-property>
</managed-bean>

В этом примере инициализируется массив или List. Тип соответствующего свойства в компоненте определяет, какая структура данных создаётся. Элемент list-entries определяет список значений в массиве или List. Элемент value указывает одно значение в массиве или List и может ссылаться на свойство в другом бине. Элемент null-value будет вызывать метод setBooks с аргументом null. Свойство null нельзя указывать для свойства, тип данных которого является примитивом Java, например int или boolean.

Инициализация свойств Managed-бина

Иногда может понадобиться создать бин, который также ссылается на другие Managed-бины, чтобы можно было построить граф или дерево бинов. Для примера предположим, что вы хотите создать компонент, представляющий информацию о клиенте, включая почтовый адрес и адрес улицы, каждый из которых также является компонентом. Следующие объявления managed-bean создают объект CustomerBean, который имеет два свойства AddressBean: одно представляет почтовый адрес, а другое — адрес улицы. Результатом этого объявления является дерево компонентов с CustomerBean в качестве его родителя и двумя объектами AddressBean в качестве дочерних.

<managed-bean>
    <managed-bean-name>customer</managed-bean-name>
    <managed-bean-class>
        com.example.mybeans.CustomerBean
    </managed-bean-class>
    <managed-bean-scope> request </managed-bean-scope>
    <managed-property>
        <property-name>mailingAddress</property-name>
        <value>#{addressBean}</value>
    </managed-property>
    <managed-property>
        <property-name>streetAddress</property-name>
        <value>#{addressBean}</value>
    </managed-property>
    <managed-property>
        <property-name>customerType</property-name>
        <value>New</value>
    </managed-property>
</managed-bean>
<managed-bean>
    <managed-bean-name>addressBean</managed-bean-name>
    <managed-bean-class>
        com.example.mybeans.AddressBean
    </managed-bean-class>
    <managed-bean-scope> none </managed-bean-scope>
    <managed-property>
        <property-name>street</property-name>
        <null-value/>
    <managed-property>
    ...
</managed-bean>

Первое объявление CustomerBeanmanaged-bean-name из customer) создаёт CustomerBean в области видимости запроса. Этот бин имеет два свойства: mailingAddress и streetAddress. Эти свойства используют элемент value для ссылки на компонент с именем addressBean.

Второе объявление Managed-бина определяет AddressBean, но не создаёт его, потому что его элемент managed-bean-scope определяет область видимости none. Напомним, что область видимости none означает, что компонент создаётся только тогда, когда на него ссылается что-то другое. Поскольку свойства mailingAddress и streetAddress ссылаются на addressBean, используя элемент value, два объекта AddressBean создаются при создании CustomerBean.

Когда вы создаёте объект, который указывает на другие объекты, не пытайтесь указывать на объект с более коротким сроком службы, потому что может быть невозможно восстановить ресурсы этой области видимости, когда объект будет удалён. Например, объект в области видимости сессии не может указывать на объект в области видимости запроса. А объекты с областью видимости none не имеют чётко заданной продолжительности жизни, управляемой фреймворком, поэтому они могут указывать только на другие объекты с областью видимости none. Таблица 16-2 описывает все разрешённые соединения.

Таблица 16-2. Допустимые соединения между объектами в области видимости

Объект этой области

Может указывать на объект этой области

none

none

application

none, application

session

none, application, session

request

none, application, session, request, view

view

none, application, session, view

Не допускайте циклических ссылок между объектами. Например, ни один из объектов AddressBean в предыдущем примере не должен указывать на объект CustomerBean, поскольку CustomerBean уже указывает на AddressBean объекты.

Инициализация отображений и списков

Помимо настройки свойств Map и List, вы также можете напрямую настроить Map и List, чтобы ссылаться на них из тега, а не через свойство, которое переносит Map или List.


Назад Вперёд Содержание
Логотип Oracle  Copyright © 2017, Oracle и/или её дочерних компаний. Все права защищены. Версия перевода 1.0.5 (Java EE Tutorial — русскоязычная версия)