type=page
status=published
title=Configuring Managed Beans
next=jsf-configure006.html
prev=jsf-configure004.html
~~~~~~
= Configuring Managed Beans


[[BNAWQ]]

[[configuring-managed-beans]]
Configuring Managed Beans
-------------------------

When a page references a managed bean for the first time, the JavaServer
Faces implementation initializes it either based on a `@Named`
annotation and scope annotation in the bean class or according to its
configuration in the application configuration resource file. For
information on using annotations to initialize beans, see
link:jsf-configure002.html#GIRCH[Using Annotations to Configure Managed
Beans].

You can use either annotations or the application configuration resource
file to instantiate managed beans that are used in a JavaServer Faces
application and to store them in scope. The managed bean creation
facility is configured in the application configuration resource file
using `managed-bean` XML elements to define each bean. This file is
processed at application startup time. For information on using this
facility, see link:#BNAWR[Using the managed-bean Element].

Managed beans created in the application configuration resource file are
JavaServer Faces managed beans, not CDI managed beans.

With the managed bean creation facility, you can

* Create beans in one centralized file that is available to the entire
application, rather than conditionally instantiate beans throughout the
application
* Customize a bean's properties without any additional code
* Customize a bean's property values directly from within the
configuration file so that it is initialized with these values when it
is created
* Using `value` elements, set a property of one managed bean to be the
result of evaluating another value expression

This section shows you how to initialize beans using the managed bean
creation facility. See link:jsf-develop002.html#BNATY[Writing Bean
Properties] and link:jsf-develop003.html#BNAVB[Writing Managed Bean
Methods] for information on programming managed beans.

[[BNAWR]]

[[using-the-managed-bean-element]]
Using the managed-bean Element
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

A managed bean is initiated in the application configuration resource
file using a `managed-bean` element, which represents an instance of a
bean class that must exist in the application. At runtime, the
JavaServer Faces implementation processes the `managed-bean` element. If
a page references the bean and no bean instance exists, the JavaServer
Faces implementation instantiates the bean as specified by the element
configuration.

Here is an example managed bean configuration from the Duke's Bookstore
case study:

[source,oac_no_warn]
----
<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>
----

The `managed-bean-name` element defines the key under which the bean
will be stored in a scope. For a component's value to map to this bean,
the component tag's `value` attribute must match the `managed-bean-name`
up to the first period.

The `managed-bean-class` element defines the fully qualified name of the
JavaBeans component class used to instantiate the bean.

The `managed-bean` element can contain zero or more `managed-property`
elements, each corresponding to a property defined in the bean class.
These elements are used to initialize the values of the bean properties.
If you don't want a particular property initialized with a value when
the bean is instantiated, do not include a `managed-property` definition
for it in your application configuration resource file.

If a `managed-bean` element does not contain other `managed-bean`
elements, it can contain one `map-entries` element or `list-entries`
element. The `map-entries` element configures a set of beans that are
instances of `Map`. The `list-entries` element configures a set of beans
that are instances of `List`.

In the following example, the `newsletters` managed bean, representing a
`UISelectItems` component, is configured as an `ArrayList` that
represents a set of `SelectItem` objects. Each `SelectItem` object is in
turn configured as a managed bean with properties:

[source,oac_no_warn]
----
<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>
...
----

This approach may be useful for quick-and-dirty creation of selection
item lists before a development team has had time to create such lists
from the database. Note that each of the individual newsletter beans has
a `managed-bean-scope` setting of `none` so that they will not
themselves be placed into any scope.

See link:#BNAWX[Initializing Array and List Properties] for more
information on configuring collections as beans.

To map to a property defined by a `managed-property` element, you must
ensure that the part of a component tag's `value` expression after the
period matches the `managed-property` element's `property-name` element.
The next section, link:#BNAWS[Initializing Properties Using the
managed-property Element], explains in more detail how to use the
`managed-property` element. See link:#BNAWY[Initializing Managed Bean
Properties] for an example of initializing a managed bean property.

[[BNAWS]]

[[initializing-properties-using-the-managed-property-element]]
Initializing Properties Using the managed-property Element
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

A `managed-property` element must contain a `property-name` element,
which must match the name of the corresponding property in the bean. A
`managed-property` element must also contain one of a set of elements
that defines the value of the property. This value must be of the same
type as that defined for the property in the corresponding bean. Which
element you use to define the value depends on the type of the property
defined in the bean. link:#BNAWT[Table 16-1] lists all the elements that
are used to initialize a value.

[[sthref94]][[BNAWT]]

*Table 16-1 Subelements of managed-property Elements That Define Property
Values*

[width="75%",cols="25%,50%"]
|=======================================================================
|*Element* |*Value It Defines*
|`list-entries` |Defines the values in a list

|`map-entries` |Defines the values of a map

|`null-value` |Explicitly sets the property to `null`

|`value` |Defines a single value, such as a `String`, `int`, or
JavaServer Faces EL expression
|=======================================================================


link:#BNAWR[Using the managed-bean Element] includes an example of
initializing an `int` property (a primitive type) using the `value`
subelement. You also use the `value` subelement to initialize `String`
and other reference types. The rest of this section describes how to use
the `value` subelement and other subelements to initialize properties of
Java `Enum` types, `Map`, `array`, and `Collection`, as well as
initialization parameters.

[[BNAWU]]

[[referencing-a-java-enum-type]]
Referencing a Java Enum Type
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

A managed bean property can also be a Java `Enum` type (see
`http://docs.oracle.com/javase/7/docs/api/java/lang/Enum.html`). In this
case, the `value` element of the `managed-property` element must be a
`String` that matches one of the `String` constants of the `Enum`. In
other words, the `String` must be one of the valid values that can be
returned if you were to call `valueOf(Class, String)` on `enum`, where
`Class` is the `Enum` class and `String` is the contents of the `value`
subelement. For example, suppose the managed bean property is the
following:

[source,oac_no_warn]
----
public enum Suit { Hearts, Spades, Diamonds, Clubs }
 ...
public Suit getSuit() { ... return Suit.Hearts; }
----

Assuming you want to configure this property in the application
configuration resource file, the corresponding `managed-property`
element looks like this:

[source,oac_no_warn]
----
<managed-property>
    <property-name>Suit</property-name>
    <value>Hearts</value>
</managed-property>
----

When the system encounters this property, it iterates over each of the
members of the `enum` and calls `toString()` on each member until it
finds one that is exactly equal to the value from the `value` element.

[[BNAWV]]

[[referencing-a-context-initialization-parameter]]
Referencing a Context Initialization Parameter
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Another powerful feature of the managed bean creation facility is the
ability to reference implicit objects from a managed bean property.

Suppose you have a page that accepts data from a customer, including the
customer's address. Suppose also that most of your customers live in a
particular area code. You can make the area code component render this
area code by saving it in an implicit object and referencing it when the
page is rendered.

You can save the area code as an initial default value in the context
`initParam` implicit object by adding a context parameter to your web
application and setting its value in the deployment descriptor. For
example, to set a context parameter called `defaultAreaCode` to `650`,
add a `context-param` element to the deployment descriptor and give the
parameter the name `defaultAreaCode` and the value `650`.

Next, write a `managed-bean` declaration that configures a property that
references the parameter:

[source,oac_no_warn]
----
<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>
----

To access the area code at the time the page is rendered, refer to the
property from the `area` component tag's `value` attribute:

[source,oac_no_warn]
----
<h:inputText id=area value="#{customer.areaCode}"
----

Values are retrieved from other implicit objects in a similar way.

[[BNAWW]]

[[initializing-map-properties]]
Initializing Map Properties
^^^^^^^^^^^^^^^^^^^^^^^^^^^

The `map-entries` element is used to initialize the values of a bean
property with a type of `Map` if the `map-entries` element is used
within a `managed-property` element. A `map-entries` element contains an
optional `key-class` element, an optional `value-class` element, and
zero or more `map-entry` elements.

Each of the `map-entry` elements must contain a `key` element and either
a `null-value` or `value` element. Here is an example that uses the
`map-entries` element:

[source,oac_no_warn]
----
<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>
----

The map created from this `map-entries` tag contains two entries. By
default, all the keys and values are converted to `String`. If you want
to specify a different type for the keys in the map, embed the
`key-class` element just inside the `map-entries` element:

[source,oac_no_warn]
----
<map-entries>
    <key-class>java.math.BigDecimal</key-class>
    ...
</map-entries>
----

This declaration will convert all the keys into `java.math.BigDecimal`.
Of course, you must make sure that the keys can be converted to the type
you specify. The key from the example in this section cannot be
converted to a `BigDecimal`, because it is a `String`.

If you want to specify a different type for all the values in the map,
include the `value-class` element after the `key-class` element:

[source,oac_no_warn]
----
<map-entries>
    <key-class>int</key-class>
    <value-class>java.math.BigDecimal</value-class>
    ...
</map-entries>
----

Note that this tag sets only the type of all the `value` subelements.

Each `map-entry` in the preceding example includes a `value` subelement.
The `value` subelement defines a single value, which will be converted
to the type specified in the bean.

Instead of using a `map-entries` element, it is also possible to assign
the entire map using a `value` element that specifies a map-typed
expression.

[[BNAWX]]

[[initializing-array-and-list-properties]]
Initializing Array and List Properties
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The `list-entries` element is used to initialize the values of an array
or `List` property. Each individual value of the array or `List` is
initialized using a `value` or `null-value` element. Here is an example:

[source,oac_no_warn]
----
<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>
----

This example initializes an array or a `List`. The type of the
corresponding property in the bean determines which data structure is
created. The `list-entries` element defines the list of values in the
array or `List`. The `value` element specifies a single value in the
array or `List` and can reference a property in another bean. The
`null-value` element will cause the `setBooks` method to be called with
an argument of `null`. A `null` property cannot be specified for a
property whose data type is a Java primitive, such as `int` or
`boolean`.

[[BNAWY]]

[[initializing-managed-bean-properties]]
Initializing Managed Bean Properties
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Sometimes you might want to create a bean that also references other
managed beans so that you can construct a graph or a tree of beans. For
example, suppose you want to create a bean representing a customer's
information, including the mailing address and street address, each of
which is also a bean. The following `managed-bean` declarations create a
`CustomerBean` instance that has two `AddressBean` properties: one
representing the mailing address and the other representing the street
address. This declaration results in a tree of beans with `CustomerBean`
as its root and the two `AddressBean` objects as children.

[source,oac_no_warn]
----
<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>
----

The first `CustomerBean` declaration (with the `managed-bean-name` of
`customer`) creates a `CustomerBean` in request scope. This bean has two
properties, `mailingAddress` and `streetAddress`. These properties use
the `value` element to reference a bean named `addressBean`.

The second managed bean declaration defines an `AddressBean` but does
not create it, because its `managed-bean-scope` element defines a scope
of `none`. Recall that a scope of `none` means that the bean is created
only when something else references it. Because both the
`mailingAddress` and the `streetAddress` properties reference
`addressBean` using the `value` element, two instances of `AddressBean`
are created when `CustomerBean` is created.

When you create an object that points to other objects, do not try to
point to an object with a shorter life span, because it might be
impossible to recover that scope's resources when it goes away. A
session-scoped object, for example, cannot point to a request-scoped
object. And objects with `none` scope have no effective life span
managed by the framework, so they can point only to other `none`-scoped
objects. link:#BNAWZ[Table 16-2] outlines all of the allowed
connections.

[[sthref95]][[BNAWZ]]

*Table 16-2 Allowable Connections between Scoped Objects*

[width="60%",cols="20%,40%"]
|==============================================================
|*An Object of This Scope* |*May Point to an Object of This Scope*
|`none` |`none`
|`application` |`none`, `application`
|`session` |`none`, `application`, `session`
|`request` |`none`, `application`, `session`, `request`, `view`
|`view` |`none`, `application`, `session`, `view`
|==============================================================


Be sure not to allow cyclical references between objects. For example,
neither of the `AddressBean` objects in the preceding example should
point back to the `CustomerBean` object, because `CustomerBean` already
points to the `AddressBean` objects.

[[BNAXA]]

[[initializing-maps-and-lists]]
Initializing Maps and Lists
~~~~~~~~~~~~~~~~~~~~~~~~~~~

In addition to configuring `Map` and `List` properties, you can also
configure a `Map` and a `List` directly so that you can reference them
from a tag rather than referencing a property that wraps a `Map` or a
`List`.
