spring-framework/spring-framework-reference/src/beans.xml

6855 lines
329 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<chapter id="beans">
<title>The IoC container</title>
<section id="beans-introduction">
<title>Introduction</title>
<para>This chapter covers the Spring Framework's implementation of the
Inversion of Control (IoC) <footnote>
<para>See the section entitled <xref
linkend="background-ioc" /></para>
</footnote> principle.</para>
<para>The <literal>org.springframework.beans</literal> and
<literal>org.springframework.context</literal> packages provide the basis
for the Spring Framework's IoC container. The <interfacename><ulink
url="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/beans/factory/BeanFactory.html">BeanFactory</ulink></interfacename>
interface provides an advanced configuration mechanism capable of managing
objects of any nature. The <literal><ulink
url="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/context/ApplicationContext.html">ApplicationContext</ulink></literal>
interface builds on top of the <interfacename>BeanFactory</interfacename>
(it is a sub-interface) and adds other functionality such as easier
integration with Spring's AOP features, message resource handling (for use
in internationalization), event propagation, and application-layer
specific contexts such as the
<interfacename>WebApplicationContext</interfacename> for use in web
applications.</para>
<para>In short, the <interfacename>BeanFactory</interfacename> provides
the configuration framework and basic functionality, while the
<interfacename>ApplicationContext</interfacename> adds more
enterprise-centric functionality to it. The
<interfacename>ApplicationContext</interfacename> is a complete superset
of the <interfacename>BeanFactory</interfacename>, and any description of
<interfacename>BeanFactory</interfacename> capabilities and behavior is to
be considered to apply to the
<interfacename>ApplicationContext</interfacename> as well.</para>
<sidebar>
<title><interfacename>BeanFactory</interfacename> or
<interfacename>ApplicationContext</interfacename>?</title>
<para>Users are sometimes unsure whether a
<interfacename>BeanFactory</interfacename> or an
<interfacename>ApplicationContext</interfacename> is best suited for use
in a particular situation. A <interfacename>BeanFactory</interfacename>
pretty much just instantiates and configures beans. An
<interfacename>ApplicationContext</interfacename> also does that,
<emphasis>and</emphasis> it provides the supporting infrastructure to
enable <emphasis>lots</emphasis> of enterprise-specific features such as
transactions and AOP.</para>
<para><emphasis role="bold">In short, favor the use of an
<interfacename>ApplicationContext</interfacename>.</emphasis></para>
<para>(For the specific details behind this recommendation, see <link
linkend="context-introduction-ctx-vs-beanfactory">this
section</link>.)</para>
</sidebar>
<para>This chapter is divided into two parts, with the <link
linkend="beans-basics">first part</link> covering the basic principles
that apply to both the <interfacename>BeanFactory</interfacename> and
<interfacename>ApplicationContext</interfacename>, and with the <link
linkend="context-introduction">second part</link> covering those features
that apply only to the <interfacename>ApplicationContext</interfacename>
interface.</para>
</section>
<section id="beans-basics">
<title>Basics - containers and beans</title>
<para>In Spring, those objects that form the backbone of your application
and that are managed by the Spring IoC <firstterm>container</firstterm>
are referred to as <firstterm>beans</firstterm>. A bean is simply an
object that is instantiated, assembled and otherwise managed by a Spring
IoC container; other than that, there is nothing special about a bean (it
is in all other respects one of probably many objects in your
application). These beans, and the <firstterm>dependencies</firstterm>
between them, are reflected in the <firstterm>configuration
metadata</firstterm> used by a container.</para>
<sidebar>
<title>Why... <emphasis>bean</emphasis>?</title>
<para>The motivation for using the name <emphasis>'bean'</emphasis>, as
opposed to <emphasis>'component'</emphasis> or
<emphasis>'object'</emphasis> is rooted in the origins of the Spring
Framework itself (it arose partly as a response to the complexity of
Enterprise Java<emphasis>Beans</emphasis>).</para>
</sidebar>
<section id="beans-factory">
<title>The container</title>
<para>The
<interfacename>org.springframework.beans.factory.BeanFactory</interfacename>
is the actual representation of the Spring IoC
<emphasis>container</emphasis> that is responsible for containing and
otherwise managing the aforementioned beans.</para>
<para>The <interfacename>BeanFactory</interfacename> interface is the
central IoC container interface in Spring. Its responsibilities include
instantiating or sourcing application objects, configuring such objects,
and assembling the dependencies between these objects.</para>
<para>There are a number of implementations of the
<interfacename>BeanFactory</interfacename> interface that come supplied
straight out-of-the-box with Spring. The most commonly used
<interfacename>BeanFactory</interfacename> implementation is the
<classname>XmlBeanFactory</classname> class. This implementation allows
you to express the objects that compose your application, and the
doubtless rich interdependencies between such objects, in terms of XML.
The <classname>XmlBeanFactory</classname> takes this XML
<firstterm>configuration metadata</firstterm> and uses it to create a
fully configured system or application.</para>
<para><mediaobject>
<imageobject role="fo">
<imagedata align="center" fileref="images/container-magic.png"
format="PNG" />
</imageobject>
<imageobject role="html">
<imagedata align="center" fileref="images/container-magic.png"
format="PNG" />
</imageobject>
<caption><para>The Spring IoC container</para></caption>
</mediaobject></para>
<section id="beans-factory-metadata">
<title>Configuration metadata</title>
<para>As can be seen in the above image, the Spring IoC container
consumes some form of <emphasis>configuration metadata</emphasis>;
this configuration metadata is nothing more than how you (as an
application developer) inform the Spring container as to how to
<emphasis><quote>instantiate, configure, and assemble [the objects in
your application]</quote>.</emphasis> This configuration metadata is
typically supplied in a simple and intuitive XML format. When using
XML-based configuration metadata, you write <emphasis>bean
definitions</emphasis> for those beans that you want the Spring IoC
container to manage, and then let the container do its stuff.</para>
<note>
<para>XML-based metadata is by far the most commonly used form of
configuration metadata. It is <emphasis>not</emphasis> however the
only form of configuration metadata that is allowed. The Spring IoC
container itself is <emphasis>totally</emphasis> decoupled from the
format in which this configuration metadata is actually written. The
XML-based configuration metadata format really is simple though, and
so the majority of this chapter will use the XML format to convey
key concepts and features of the Spring IoC container.</para>
<para>You can find details of another form of metadata that the
Spring container can consume in the section entitled <xref
linkend="beans-annotation-config" /></para>
</note>
<sidebar>
<title>Resources</title>
<para>The location path or paths supplied to an
<interfacename>ApplicationContext</interfacename> constructor are
actually resource strings that allow the container to load
configuration metadata from a variety of external resources such as
the local file system, from the Java <literal>CLASSPATH</literal>,
etc.</para>
<para>Once you have learned about Spring's IoC container, you may
wish to learn a little more about Spring's
<interfacename>Resource</interfacename> abstraction, as described in
the chapter entitled <xref linkend="resources" />.</para>
</sidebar>
<para>In the vast majority of application scenarios, explicit user
code is not required to instantiate one or more instances of a Spring
IoC container. For example, in a web application scenario, a simple
eight (or so) lines of boilerplate J2EE web descriptor XML in the
<literal>web.xml</literal> file of the application will typically
suffice (see <xref linkend="context-create" />).</para>
<para>Spring configuration consists of at least one bean definition
that the container must manage, but typically there will be more than
one bean definition. When using XML-based configuration metadata,
these beans are configured as <literal>&lt;bean/&gt;</literal>
elements inside a top-level <literal>&lt;beans/&gt;</literal>
element.</para>
<para>These bean definitions correspond to the actual objects that
make up your application. Typically you will have bean definitions for
your service layer objects, your data access objects (DAOs),
presentation objects such as Struts
<interfacename>Action</interfacename> instances, infrastructure
objects such as Hibernate
<interfacename>SessionFactories</interfacename>, JMS
<interfacename>Queues</interfacename>, and so forth. Typically one
does not configure fine-grained domain objects in the container,
because it is usually the responsibility of DAOs and business logic to
create/load domain objects.</para>
<para>Find below an example of the basic structure of XML-based
configuration metadata.</para>
<programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"&gt;
&lt;bean id="..." class="..."&gt;
&lt;!-- collaborators and configuration for this bean go here --&gt;
&lt;/bean&gt;
&lt;bean id="..." class="..."&gt;
&lt;!-- collaborators and configuration for this bean go here --&gt;
&lt;/bean&gt;
&lt;!-- more bean definitions go here --&gt;
&lt;/beans&gt;</programlisting>
</section>
</section>
<section id="beans-factory-instantiation">
<title>Instantiating a container</title>
<para>Instantiating a Spring IoC container is straightforward.</para>
<programlisting language="java">ApplicationContext context = new ClassPathXmlApplicationContext(
new String[] {"services.xml", "daos.xml"});
<lineannotation>// an <interfacename>ApplicationContext</interfacename> is also a <interfacename>BeanFactory</interfacename> (via inheritance)</lineannotation>
BeanFactory factory = context;</programlisting>
<section id="beans-factory-xml-import">
<title>Composing XML-based configuration metadata</title>
<para>It can often be useful to split up container definitions into
multiple XML files. One way to then load an application context which
is configured from all these XML fragments is to use the application
context constructor which takes multiple
<interfacename>Resource</interfacename> locations. With a bean
factory, a bean definition reader can be used multiple times to read
definitions from each file in turn.</para>
<para>Generally, the Spring team prefers the above approach, since it
keeps container configuration files unaware of the fact that they are
being combined with others. An alternate approach is to use one or
more occurrences of the <literal>&lt;import/&gt;</literal> element to
load bean definitions from another file (or files). Let's look at a
sample:</para>
<programlisting language="xml">&lt;beans&gt;
&lt;import resource="services.xml"/&gt;
&lt;import resource="resources/messageSource.xml"/&gt;
&lt;import resource="/resources/themeSource.xml"/&gt;
&lt;bean id="bean1" class="..."/&gt;
&lt;bean id="bean2" class="..."/&gt;
&lt;/beans&gt;</programlisting>
<para>In this example, external bean definitions are being loaded from
3 files, <literal>services.xml</literal>,
<literal>messageSource.xml</literal>, and
<literal>themeSource.xml</literal>. All location paths are considered
relative to the definition file doing the importing, so
<literal>services.xml</literal> in this case must be in the same
directory or classpath location as the file doing the importing, while
<literal>messageSource.xml</literal> and
<literal>themeSource.xml</literal> must be in a
<literal>resources</literal> location below the location of the
importing file. As you can see, a leading slash is actually ignored,
but given that these are considered relative paths, it is probably
better form not to use the slash at all. The contents of the files
being imported must be valid XML bean definition files according to
the Spring Schema or DTD, including the top level
<literal>&lt;beans/&gt;</literal> element.</para>
<note>
<para>It is possible to reference files in parent directories using
a relative "../" path. However, this is not recommended because it
creates a dependency on a file that is outside the current
application. This is in particular not recommended for "classpath:"
URLs (e.g. "classpath:../services.xml") where the runtime resolution
process will pick the "nearest" classpath root and then look into
its parent directory. This is fragile since classpath configuration
changes may lead to a different directory being picked.</para>
<para>Note that you can always use fully qualified resource
locations instead of relative paths: e.g.
"file:C:/config/services.xml" or "classpath:/config/services.xml".
However, be aware that you are coupling your application's
configuration to specific absolute locations then. It is generally
preferable to keep an indirection for such absolute locations, e.g.
through "${...}" placeholders that are resolved against JVM system
properties at runtime.</para>
</note>
</section>
</section>
<section id="beans-definition">
<title>The beans</title>
<para>A Spring IoC container manages one or more
<emphasis>beans</emphasis>. These beans are created using the
configuration metadata that has been supplied to the container
(typically in the form of XML <literal>&lt;bean/&gt;</literal>
definitions).</para>
<para>Within the container itself, these bean definitions are
represented as <interfacename>BeanDefinition</interfacename> objects,
which contain (among other information) the following metadata:</para>
<itemizedlist>
<listitem>
<para><emphasis>a package-qualified class name:</emphasis> typically
this is the actual implementation class of the bean being
defined.</para>
</listitem>
<listitem>
<para>bean behavioral configuration elements, which state how the
bean should behave in the container (scope, lifecycle callbacks, and
so forth).</para>
</listitem>
<listitem>
<para>references to other beans which are needed for the bean to do
its work; these references are also called
<emphasis>collaborators</emphasis> or
<emphasis>dependencies</emphasis>.</para>
</listitem>
<listitem>
<para>other configuration settings to set in the newly created
object. An example would be the number of connections to use in a
bean that manages a connection pool, or the size limit of the
pool.</para>
</listitem>
</itemizedlist>
<para>The concepts listed above directly translate to a set of
properties that each bean definition consists of. Some of these
properties are listed below, along with a link to further documentation
about each of them.</para>
<table id="beans-factory-bean-definition-tbl">
<title>The bean definition</title>
<tgroup cols="2">
<colspec colname="c1" colwidth="2*" />
<colspec colname="c2" colwidth="4*" />
<thead>
<row>
<entry>Feature</entry>
<entry>Explained in...</entry>
</row>
</thead>
<tbody>
<row>
<entry>class</entry>
<entry><para> <xref linkend="beans-factory-class" />
</para></entry>
</row>
<row>
<entry>name</entry>
<entry><para> <xref linkend="beans-beanname" /> </para></entry>
</row>
<row>
<entry>scope</entry>
<entry><para> <xref linkend="beans-factory-scopes" />
</para></entry>
</row>
<row>
<entry>constructor arguments</entry>
<entry><para> <xref linkend="beans-factory-collaborators" />
</para></entry>
</row>
<row>
<entry>properties</entry>
<entry><para> <xref linkend="beans-factory-collaborators" />
</para></entry>
</row>
<row>
<entry>autowiring mode</entry>
<entry><para> <xref linkend="beans-factory-autowire" />
</para></entry>
</row>
<row>
<entry>dependency checking mode</entry>
<entry><para> <xref linkend="beans-factory-dependencies" />
</para></entry>
</row>
<row>
<entry>lazy-initialization mode</entry>
<entry><para> <xref linkend="beans-factory-lazy-init" />
</para></entry>
</row>
<row>
<entry>initialization method</entry>
<entry><para> <xref
linkend="beans-factory-lifecycle-initializingbean" />
</para></entry>
</row>
<row>
<entry>destruction method</entry>
<entry><para> <xref
linkend="beans-factory-lifecycle-disposablebean" />
</para></entry>
</row>
</tbody>
</tgroup>
</table>
<para>Besides bean definitions which contain information on how to
create a specific bean, certain
<interfacename>BeanFactory</interfacename> implementations also permit
the registration of existing objects that have been created outside the
factory (by user code). The
<classname>DefaultListableBeanFactory</classname> class supports this
through the <methodname>registerSingleton(..)</methodname> method.
(Typical applications solely work with beans defined through metadata
bean definitions though.)</para>
<section id="beans-beanname">
<title>Naming beans</title>
<sidebar>
<title>Bean naming conventions</title>
<para>The convention (at least amongst the Spring development team)
is to use the standard Java convention for instance field names when
naming beans. That is, bean names start with a lowercase letter, and
are camel-cased from then on. Examples of such names would be
(without quotes) <literal>'accountManager'</literal>,
<literal>'accountService'</literal>, <literal>'userDao'</literal>,
<literal>'loginController'</literal>, and so forth.</para>
<para>Adopting a consistent way of naming your beans will go a long
way towards making your configuration easier to read and understand;
adopting such naming standards is not hard to do, and if you are
using Spring AOP it can pay off handsomely when it comes to applying
advice to a set of beans related by name.</para>
</sidebar>
<para>Every bean has one or more <literal>id</literal>s (also called
identifiers, or names; these terms refer to the same thing). These
<literal>id</literal>s must be unique within the container the bean is
hosted in. A bean will almost always have only one id, but if a bean
has more than one id, the extra ones can essentially be considered
aliases.</para>
<para>When using XML-based configuration metadata, you use the
<literal>'id'</literal> or <literal>'name'</literal> attributes to
specify the bean identifier(s). The <literal>'id'</literal> attribute
allows you to specify exactly one id, and as it is a real XML element
ID attribute, the XML parser is able to do some extra validation when
other elements reference the id; as such, it is the preferred way to
specify a bean id. However, the XML specification does limit the
characters which are legal in XML IDs. This is usually not a
constraint, but if you have a need to use one of these special XML
characters, or want to introduce other aliases to the bean, you may
also or instead specify one or more bean <literal>id</literal>s,
separated by a comma (<literal>,</literal>), semicolon
(<literal>;</literal>), or whitespace in the <literal>'name'</literal>
attribute.</para>
<para>Please note that you are not required to supply a name for a
bean. If no name is supplied explicitly, the container will generate a
unique name for that bean. The motivations for not supplying a name
for a bean will be discussed later (one use case is <link
linkend="beans-inner-beans">inner beans</link>).</para>
<section id="beans-beanname-alias">
<title>Aliasing beans</title>
<para>In a bean definition itself, you may supply more than one name
for the bean, by using a combination of up to one name specified via
the <literal>id</literal> attribute, and any number of other names
via the <literal>name</literal> attribute. All these names can be
considered equivalent aliases to the same bean, and are useful for
some situations, such as allowing each component used in an
application to refer to a common dependency using a bean name that
is specific to that component itself.</para>
<para>Having to specify all aliases when the bean is actually
defined is not always adequate however. It is sometimes desirable to
introduce an alias for a bean which is defined elsewhere. In
XML-based configuration metadata this may be accomplished via the
use of the <literal>&lt;alias/&gt;</literal> element.</para>
<programlisting language="xml">&lt;alias name="fromName" alias="toName"/&gt;</programlisting>
<para>In this case, a bean in the same container which is named
<literal>'fromName'</literal>, may also after the use of this alias
definition, be referred to as <literal>'toName'</literal>.</para>
<para>As a concrete example, consider the case where component A
defines a DataSource bean called componentA-dataSource, in its XML
fragment. Component B would however like to refer to the DataSource
as componentB-dataSource in its XML fragment. And the main
application, MyApp, defines its own XML fragment and assembles the
final application context from all three fragments, and would like
to refer to the DataSource as myApp-dataSource. This scenario can be
easily handled by adding to the MyApp XML fragment the following
standalone aliases:</para>
<programlisting language="xml">&lt;alias name="componentA-dataSource" alias="componentB-dataSource"/&gt;
&lt;alias name="componentA-dataSource" alias="myApp-dataSource" /&gt;</programlisting>
<para>Now each component and the main application can refer to the
dataSource via a name that is unique and guaranteed not to clash
with any other definition (effectively there is a namespace), yet
they refer to the same bean.</para>
</section>
</section>
<section id="beans-factory-class">
<title>Instantiating beans</title>
<sidebar>
<title>Inner class names</title>
<para>If for whatever reason you want to configure a bean definition
for a <literal>static</literal> inner class, you have to use the
<emphasis>binary</emphasis> name of the inner class.</para>
<para>For example, if you have a class called
<classname>Foo</classname> in the <literal>com.example</literal>
package, and this <classname>Foo</classname> class has a
<literal>static</literal> inner class called
<classname>Bar</classname>, the value of the
<literal>'class'</literal> attribute on a bean definition would
be...</para>
<para><classname>com.example.Foo$Bar</classname></para>
<para>Notice the use of the <literal>$</literal> character in the
name to separate the inner class name from the outer class
name.</para>
</sidebar>
<para>A bean definition essentially is a recipe for creating one or
more objects. The container looks at the recipe for a named bean when
asked, and uses the configuration metadata encapsulated by that bean
definition to create (or acquire) an actual object.</para>
<para>If you are using XML-based configuration metadata, you can
specify the type (or class) of object that is to be instantiated using
the <literal>'class'</literal> attribute of the
<literal>&lt;bean/&gt;</literal> element. This
<literal>'class'</literal> attribute (which internally eventually
boils down to being a <classname>Class</classname> property on a
<interfacename>BeanDefinition</interfacename> instance) is normally
mandatory (see <xref
linkend="beans-factory-class-instance-factory-method" /> and <xref
linkend="beans-child-bean-definitions" /> for the two exceptions) and
is used for one of two purposes. The class property specifies the
class of the bean to be constructed in the common case where the
container itself directly creates the bean by calling its constructor
reflectively (somewhat equivalent to Java code using the
<emphasis>'new'</emphasis> operator). In the less common case where
the container invokes a <literal>static</literal>,
<emphasis>factory</emphasis> method on a class to create the bean, the
class property specifies the actual class containing the
<literal>static</literal> factory method that is to be invoked to
create the object (the type of the object returned from the invocation
of the <literal>static</literal> factory method may be the same class
or another class entirely, it doesn't matter).</para>
<section id="beans-factory-class-ctor">
<title>Instantiation using a constructor</title>
<para>When creating a bean using the constructor approach, all
normal classes are usable by and compatible with Spring. That is,
the class being created does not need to implement any specific
interfaces or be coded in a specific fashion. Just specifying the
bean class should be enough. However, depending on what type of IoC
you are going to use for that specific bean, you may need a default
(empty) constructor.</para>
<para>Additionally, the Spring IoC container isn't limited to just
managing true JavaBeans, it is also able to manage virtually
<emphasis>any</emphasis> class you want it to manage. Most people
using Spring prefer to have actual JavaBeans (having just a default
(no-argument) constructor and appropriate setters and getters
modeled after the properties) in the container, but it is also
possible to have more exotic non-bean-style classes in your
container. If, for example, you need to use a legacy connection pool
that absolutely does not adhere to the JavaBean specification,
Spring can manage it as well.</para>
<para>When using XML-based configuration metadata you can specify
your bean class like so:</para>
<programlisting language="xml">&lt;bean id="exampleBean" class="examples.ExampleBean"/&gt;
&lt;bean name="anotherExample" class="examples.ExampleBeanTwo"/&gt;</programlisting>
<para>The mechanism for supplying arguments to the constructor (if
required), or setting properties of the object instance after it has
been constructed, <link linkend="beans-factory-collaborators">is
described shortly</link>.</para>
</section>
<section id="beans-factory-class-static-factory-method">
<title>Instantiation using a static factory method</title>
<para>When defining a bean which is to be created using a static
factory method, along with the <literal>class</literal> attribute
which specifies the class containing the <literal>static</literal>
factory method, another attribute named
<literal>factory-method</literal> is needed to specify the name of
the factory method itself. Spring expects to be able to call this
method (with an optional list of arguments as described later) and
get back a live object, which from that point on is treated as if it
had been created normally via a constructor. One use for such a bean
definition is to call <literal>static</literal> factories in legacy
code.</para>
<para>The following example shows a bean definition which specifies
that the bean is to be created by calling a factory-method. Note
that the definition does not specify the type (class) of the
returned object, only the class containing the factory method. In
this example, the <methodname>createInstance()</methodname> method
must be a <emphasis>static</emphasis> method.</para>
<programlisting language="xml">&lt;bean id="exampleBean"
class="examples.ExampleBean2"
factory-method="createInstance"/&gt;</programlisting>
<para>The mechanism for supplying (optional) arguments to the
factory method, or setting properties of the object instance after
it has been returned from the factory, will be <link
linkend="beans-factory-properties-detailed">described
shortly</link>.</para>
</section>
<section id="beans-factory-class-instance-factory-method">
<title>Instantiation using an instance factory method</title>
<para>In a fashion similar to instantiation via a <link
linkend="beans-factory-class-static-factory-method">static factory
method</link>, instantiation using an instance factory method is
where a non-static method of an existing bean from the container is
invoked to create a new bean. To use this mechanism, the
<literal>'class'</literal> attribute must be left empty, and the
<literal>'factory-bean'</literal> attribute must specify the name of
a bean in the current (or parent/ancestor) container that contains
the instance method that is to be invoked to create the object. The
name of the factory method itself must be set using the
<literal>'factory-method'</literal> attribute.</para>
<programlisting language="xml"><lineannotation>&lt;!-- the factory bean, which contains a method called <methodname>createInstance()</methodname> --&gt;</lineannotation>
&lt;bean id="serviceLocator" class="com.foo.DefaultServiceLocator"&gt;
<lineannotation>&lt;!-- inject any dependencies required by this locator bean --&gt;</lineannotation>
&lt;/bean&gt;
<lineannotation>&lt;!-- the bean to be created via the factory bean --&gt;</lineannotation>
&lt;bean id="exampleBean"
factory-bean="serviceLocator"
factory-method="createInstance"/&gt;</programlisting>
<para>Although the mechanisms for <link
linkend="beans-factory-properties-detailed">setting bean
properties</link> are still to be discussed, one implication of this
approach is that the factory bean itself can be managed and
configured via DI.</para>
<note>
<para>When the Spring documentation makes mention of a 'factory
bean', this will be a reference to a bean that is configured in
the Spring container that will create objects via an <link
linkend="beans-factory-class-instance-factory-method">instance</link>
or <link
linkend="beans-factory-class-static-factory-method">static</link>
factory method. When the documentation mentions a
<interfacename>FactoryBean</interfacename> (notice the
capitalization) this is a reference to a Spring-specific <link
linkend="beans-factory-extension-factorybean">
<interfacename>FactoryBean</interfacename> </link>.</para>
</note>
</section>
</section>
</section>
<section id="beans-factory-client">
<title>Using the container</title>
<para>A <interfacename>BeanFactory</interfacename> is essentially
nothing more than the interface for an advanced factory capable of
maintaining a registry of different beans and their dependencies. The
<interfacename>BeanFactory</interfacename> enables you to read bean
definitions and access them using the bean factory. When using just the
<interfacename>BeanFactory</interfacename> you would create one and read
in some bean definitions in the XML format as follows:</para>
<programlisting language="java">Resource res = new FileSystemResource("beans.xml");
BeanFactory factory = new XmlBeanFactory(res);</programlisting>
<para>Basically that is all there is to it. Using
<methodname>getBean(String)</methodname> you can retrieve instances of
your beans; the client-side view of the
<interfacename>BeanFactory</interfacename> is simple. The
<interfacename>BeanFactory</interfacename> interface has just a few
other methods, but ideally your application code should never use
them... indeed, your application code should have no calls to the
<methodname>getBean(String)</methodname> method at all, and thus no
dependency on Spring APIs at all.</para>
</section>
</section>
<section id="beans-dependencies">
<title>Dependencies</title>
<para>Your typical enterprise application is not made up of a single
object (or bean in the Spring parlance). Even the simplest of applications
will no doubt have at least a handful of objects that work together to
present what the end-user sees as a coherent application. This next
section explains how you go from defining a number of bean definitions
that stand-alone, each to themselves, to a fully realized application
where objects work (or collaborate) together to achieve some goal (usually
an application that does what the end-user wants).</para>
<section id="beans-factory-collaborators">
<title>Injecting dependencies</title>
<para>The basic principle behind <emphasis>Dependency
Injection</emphasis> (DI) is that objects define their dependencies
(that is to say the other objects they work with) only through
constructor arguments, arguments to a factory method, or properties
which are set on the object instance after it has been constructed or
returned from a factory method. Then, it is the job of the container to
actually <emphasis>inject</emphasis> those dependencies when it creates
the bean. This is fundamentally the inverse, hence the name
<emphasis>Inversion of Control</emphasis> (IoC), of the bean itself
being in control of instantiating or locating its dependencies on its
own using direct construction of classes, or something like the
<emphasis>Service Locator</emphasis> pattern.</para>
<para>It becomes evident upon usage that code gets much cleaner when the
DI principle is applied, and reaching a higher grade of decoupling is
much easier when objects do not look up their dependencies, but are
provided with them (and additionally do not even know where the
dependencies are located and of what concrete class they are). DI exists
in two major variants, namely <link
linkend="beans-constructor-injection">Constructor Injection</link> and
<link linkend="beans-setter-injection">Setter Injection</link>.</para>
<section id="beans-constructor-injection">
<title>Constructor Injection</title>
<para><emphasis>Constructor-based</emphasis> DI is effected by
invoking a constructor with a number of arguments, each representing a
dependency. Additionally, calling a <literal>static</literal> factory
method with specific arguments to construct the bean, can be
considered almost equivalent, and the rest of this text will consider
arguments to a constructor and arguments to a
<literal>static</literal> factory method similarly. Find below an
example of a class that could only be dependency injected using
constructor injection. Notice that there is nothing
<emphasis>special</emphasis> about this class.</para>
<programlisting language="java">public class SimpleMovieLister {
<lineannotation>// the <classname>SimpleMovieLister</classname> has a dependency on a <interfacename>MovieFinder</interfacename></lineannotation>
private MovieFinder movieFinder;
<lineannotation>// a constructor so that the Spring container can 'inject' a <interfacename>MovieFinder</interfacename></lineannotation>
public SimpleMovieLister(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
<lineannotation>// business logic that actually 'uses' the injected <interfacename>MovieFinder</interfacename> is omitted...</lineannotation>
}</programlisting>
<section id="beans-factory-ctor-arguments-resolution">
<title>Constructor Argument Resolution</title>
<para>Constructor argument resolution matching occurs using the
argument's type. If there is no potential for ambiguity in the
constructor arguments of a bean definition, then the order in which
the constructor arguments are defined in a bean definition is the
order in which those arguments will be supplied to the appropriate
constructor when it is being instantiated. Consider the following
class:</para>
<programlisting language="java">package x.y;
public class Foo {
public Foo(Bar bar, Baz baz) {
<lineannotation>// ...</lineannotation>
}
}</programlisting>
<para>There is no potential for ambiguity here (assuming of course
that <classname>Bar</classname> and <classname>Baz</classname>
classes are not related in an inheritance hierarchy). Thus the
following configuration will work just fine, and you do not need to
specify the constructor argument indexes and / or types
explicitly.</para>
<programlisting language="xml">&lt;beans&gt;
&lt;bean name="foo" class="x.y.Foo"&gt;
&lt;constructor-arg&gt;
&lt;bean class="x.y.Bar"/&gt;
&lt;/constructor-arg&gt;
&lt;constructor-arg&gt;
&lt;bean class="x.y.Baz"/&gt;
&lt;/constructor-arg&gt;
&lt;/bean&gt;
&lt;/beans&gt;</programlisting>
<para>When another bean is referenced, the type is known, and
matching can occur (as was the case with the preceding example).
When a simple type is used, such as
<literal>&lt;value&gt;true&lt;value&gt;</literal>, Spring cannot
determine the type of the value, and so cannot match by type without
help. Consider the following class:</para>
<programlisting language="java">package examples;
public class ExampleBean {
<lineannotation>// No. of years to the calculate the Ultimate Answer</lineannotation>
private int years;
<lineannotation>// The Answer to Life, the Universe, and Everything</lineannotation>
private String ultimateAnswer;
public ExampleBean(int years, String ultimateAnswer) {
this.years = years;
this.ultimateAnswer = ultimateAnswer;
}
}</programlisting>
<section id="beans-factory-ctor-arguments-type">
<title>Constructor Argument Type Matching</title>
<para>The above scenario <emphasis>can</emphasis> use type
matching with simple types by explicitly specifying the type of
the constructor argument using the <literal>'type'</literal>
attribute. For example:</para>
<programlisting language="xml">&lt;bean id="exampleBean" class="examples.ExampleBean"&gt;
&lt;constructor-arg type="int" value="7500000"/&gt;
&lt;constructor-arg type="java.lang.String" value="42"/&gt;
&lt;/bean&gt;</programlisting>
</section>
<section id="beans-factory-ctor-arguments-index">
<title>Constructor Argument Index</title>
<para>Constructor arguments can have their index specified
explicitly by use of the <literal>index</literal> attribute. For
example:</para>
<programlisting language="xml">&lt;bean id="exampleBean" class="examples.ExampleBean"&gt;
&lt;constructor-arg index="0" value="7500000"/&gt;
&lt;constructor-arg index="1" value="42"/&gt;
&lt;/bean&gt;</programlisting>
<para>As well as solving the ambiguity problem of multiple simple
values, specifying an index also solves the problem of ambiguity
where a constructor may have two arguments of the same type. Note
that the <emphasis>index is 0 based</emphasis>.</para>
</section>
</section>
</section>
<section id="beans-setter-injection">
<title>Setter Injection</title>
<para><emphasis>Setter-based</emphasis> DI is realized by calling
setter methods on your beans after invoking a no-argument constructor
or no-argument <literal>static</literal> factory method to instantiate
your bean.</para>
<para>Find below an example of a class that can only be dependency
injected using pure setter injection. Note that there is nothing
<emphasis>special</emphasis> about this class... it is plain old
Java.</para>
<programlisting language="java">public class SimpleMovieLister {
<lineannotation>// the <classname>SimpleMovieLister</classname> has a dependency on the <interfacename>MovieFinder</interfacename></lineannotation>
private MovieFinder movieFinder;
<lineannotation>// a setter method so that the Spring container can 'inject' a <interfacename>MovieFinder</interfacename></lineannotation>
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
<lineannotation>// business logic that actually 'uses' the injected <interfacename>MovieFinder</interfacename> is omitted...</lineannotation>
}</programlisting>
<sidebar>
<title>Constructor- or Setter-based DI?</title>
<para>The Spring team generally advocates the usage of setter
injection, since a large number of constructor arguments can get
unwieldy, especially when some properties are optional. The presence
of setter methods also makes objects of that class amenable to being
re-configured (or re-injected) at some later time (for management
via <link linkend="jmx">JMX MBeans</link> is a particularly
compelling use case).</para>
<para>Constructor-injection is favored by some purists though (and
with good reason). Supplying all of an object's dependencies means
that that object is never returned to client (calling) code in a
less than totally initialized state. The flip side is that the
object becomes less amenable to re-configuration (or
re-injection).</para>
<para>There is no hard and fast rule here. Use whatever type of DI
makes the most sense for a particular class; sometimes, when dealing
with third party classes to which you do not have the source, the
choice will already have been made for you - a legacy class may not
expose any setter methods, and so constructor injection will be the
only type of DI available to you.</para>
</sidebar>
<para>The <interfacename>BeanFactory</interfacename> supports both of
these variants for injecting dependencies into beans it manages. (It
in fact also supports injecting setter-based dependencies after some
dependencies have already been supplied via the constructor approach.)
The configuration for the dependencies comes in the form of a
<interfacename>BeanDefinition</interfacename>, which is used together
with <interfacename>PropertyEditor</interfacename> instances to know
how to convert properties from one format to another. However, most
users of Spring will not be dealing with these classes directly (that
is programmatically), but rather with an XML definition file which
will be converted internally into instances of these classes, and used
to load an entire Spring IoC container instance.</para>
<para>Bean dependency resolution generally happens as follows:</para>
<orderedlist>
<listitem>
<para>The <interfacename>BeanFactory</interfacename> is created
and initialized with a configuration which describes all the
beans. (Most Spring users use a
<interfacename>BeanFactory</interfacename> or
<interfacename>ApplicationContext</interfacename> implementation
that supports XML format configuration files.)</para>
</listitem>
<listitem>
<para>Each bean has dependencies expressed in the form of
properties, constructor arguments, or arguments to the
static-factory method when that is used instead of a normal
constructor. These dependencies will be provided to the bean,
<emphasis>when the bean is actually created</emphasis>.</para>
</listitem>
<listitem>
<para>Each property or constructor argument is either an actual
definition of the value to set, or a reference to another bean in
the container.</para>
</listitem>
<listitem>
<para><anchor id="beans-factory-collaborators-propertyeditor" />
Each property or constructor argument which is a value must be
able to be converted from whatever format it was specified in, to
the actual type of that property or constructor argument. By
default Spring can convert a value supplied in string format to
all built-in types, such as <literal>int</literal>,
<literal>long</literal>, <literal>String</literal>,
<literal>boolean</literal>, etc.</para>
</listitem>
</orderedlist>
<para>The Spring container validates the configuration of each bean as
the container is created, including the validation that properties
which are bean references are actually referring to valid beans.
However, the bean properties themselves are not set until the bean
<emphasis>is actually created</emphasis>. For those beans that are
singleton-scoped and set to be pre-instantiated (such as singleton
beans in an <interfacename>ApplicationContext</interfacename>),
creation happens at the time that the container is created, but
otherwise this is only when the bean is requested. When a bean
actually has to be created, this will potentially cause a graph of
other beans to be created, as its dependencies and its dependencies'
dependencies (and so on) are created and assigned.</para>
<sidebar>
<title>Circular dependencies</title>
<para>If you are using predominantly constructor injection it is
possible to write and configure your classes and beans such that an
unresolvable circular dependency scenario is created.</para>
<para>Consider the scenario where you have class A, which requires
an instance of class B to be provided via constructor injection, and
class B, which requires an instance of class A to be provided via
constructor injection. If you configure beans for classes A and B to
be injected into each other, the Spring IoC container will detect
this circular reference at runtime, and throw a
<classname>BeanCurrentlyInCreationException</classname>.</para>
<para>One possible solution to this issue is to edit the source code
of some of your classes to be configured via setters instead of via
constructors. Another solution is not to use constructor injection
and stick to setter injection only. In other words, while it should
generally be avoided in all but the rarest of circumstances, it is
possible to configure circular dependencies with setter
injection.</para>
<para>Unlike the <emphasis>typical</emphasis> case (with no circular
dependencies), a circular dependency between bean A and bean B will
force one of the beans to be injected into the other prior to being
fully initialized itself (a classic chicken/egg scenario).</para>
</sidebar>
<para>You can generally trust Spring to do the right thing. It will
detect misconfiguration issues, such as references to non-existent
beans and circular dependencies, at container load-time. It will
actually set properties and resolve dependencies as late as possible,
which is when the bean is actually created. This means that a Spring
container which has loaded correctly can later generate an exception
when you request a bean if there is a problem creating that bean or
one of its dependencies. This could happen if the bean throws an
exception as a result of a missing or invalid property, for example.
This potentially delayed visibility of some configuration issues is
why <interfacename>ApplicationContext</interfacename> implementations
by default pre-instantiate singleton beans. At the cost of some
upfront time and memory to create these beans before they are actually
needed, you find out about configuration issues when the
<interfacename>ApplicationContext</interfacename> is created, not
later. If you wish, you can still override this default behavior and
set any of these singleton beans to lazy-initialize (that is not be
pre-instantiated).</para>
<para>If no circular dependencies are involved (see sidebar for a
discussion of circular dependencies), when one or more collaborating
beans are being injected into a dependent bean, each collaborating
bean is <emphasis>totally</emphasis> configured prior to being passed
(via one of the DI flavors) to the dependent bean. This means that if
bean A has a dependency on bean B, the Spring IoC container will
<emphasis>totally</emphasis> configure bean B prior to invoking the
setter method on bean A; you can read '<emphasis>totally
configure</emphasis>' to mean that the bean will be instantiated (if
not a pre-instantiated singleton), all of its dependencies will be
set, and the relevant lifecycle methods (such as a <link
linkend="beans-factory-lifecycle-initializingbean">configured init
method</link> or the <link
linkend="beans-factory-lifecycle-initializingbean">IntializingBean
callback method</link>) will all be invoked.</para>
</section>
<section id="beans-some-examples">
<title>Some examples</title>
<para>First, an example of using XML-based configuration metadata for
setter-based DI. Find below a small part of a Spring XML configuration
file specifying some bean definitions.</para>
<programlisting language="xml">&lt;bean id="exampleBean" class="examples.ExampleBean"&gt;
<lineannotation>&lt;!-- setter injection using the nested <literal>&lt;ref/&gt;</literal> element --&gt;</lineannotation>
&lt;property name="beanOne"&gt;&lt;ref bean="anotherExampleBean"/&gt;&lt;/property&gt;
<lineannotation>&lt;!-- setter injection using the neater 'ref' attribute --&gt;</lineannotation>
&lt;property name="beanTwo" ref="yetAnotherBean"/&gt;
&lt;property name="integerProperty" value="1"/&gt;
&lt;/bean&gt;
&lt;bean id="anotherExampleBean" class="examples.AnotherBean"/&gt;
&lt;bean id="yetAnotherBean" class="examples.YetAnotherBean"/&gt;</programlisting>
<programlisting language="java">public class ExampleBean {
private AnotherBean beanOne;
private YetAnotherBean beanTwo;
private int i;
public void setBeanOne(AnotherBean beanOne) {
this.beanOne = beanOne;
}
public void setBeanTwo(YetAnotherBean beanTwo) {
this.beanTwo = beanTwo;
}
public void setIntegerProperty(int i) {
this.i = i;
}
}</programlisting>
<para>As you can see, setters have been declared to match against the
properties specified in the XML file. Find below an example of using
constructor-based DI.</para>
<programlisting language="xml">&lt;bean id="exampleBean" class="examples.ExampleBean"&gt;
<lineannotation>&lt;!-- constructor injection using the nested <literal>&lt;ref/&gt;</literal> element --&gt;</lineannotation>
&lt;constructor-arg&gt;
&lt;ref bean="anotherExampleBean"/&gt;
&lt;/constructor-arg&gt;
<lineannotation>&lt;!-- constructor injection using the neater 'ref' attribute --&gt;</lineannotation>
&lt;constructor-arg ref="yetAnotherBean"/&gt;
&lt;constructor-arg type="int" value="1"/&gt;
&lt;/bean&gt;
&lt;bean id="anotherExampleBean" class="examples.AnotherBean"/&gt;
&lt;bean id="yetAnotherBean" class="examples.YetAnotherBean"/&gt;</programlisting>
<programlisting language="java">public class ExampleBean {
private AnotherBean beanOne;
private YetAnotherBean beanTwo;
private int i;
public ExampleBean(
AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) {
this.beanOne = anotherBean;
this.beanTwo = yetAnotherBean;
this.i = i;
}
}</programlisting>
<para>As you can see, the constructor arguments specified in the bean
definition will be used to pass in as arguments to the constructor of
the <classname>ExampleBean</classname>.</para>
<para>Now consider a variant of this where instead of using a
constructor, Spring is told to call a <literal>static</literal>
factory method to return an instance of the object:</para>
<programlisting language="xml">&lt;bean id="exampleBean" class="examples.ExampleBean"
factory-method="createInstance"&gt;
&lt;constructor-arg ref="anotherExampleBean"/&gt;
&lt;constructor-arg ref="yetAnotherBean"/&gt;
&lt;constructor-arg value="1"/&gt;
&lt;/bean&gt;
&lt;bean id="anotherExampleBean" class="examples.AnotherBean"/&gt;
&lt;bean id="yetAnotherBean" class="examples.YetAnotherBean"/&gt;</programlisting>
<programlisting language="java">public class ExampleBean {
<lineannotation>// a private constructor</lineannotation>
private ExampleBean(...) {
...
}
<lineannotation>
// a static factory method; the arguments to this method can be
// considered the dependencies of the bean that is returned,
// regardless of how those arguments are actually used.</lineannotation>
public static ExampleBean createInstance (
AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) {
ExampleBean eb = new ExampleBean (...);
<lineannotation>// some other operations...</lineannotation>
return eb;
}
}</programlisting>
<para>Note that arguments to the <literal>static</literal> factory
method are supplied via <literal>&lt;constructor-arg/&gt;</literal>
elements, exactly the same as if a constructor had actually been used.
Also, it is important to realize that the type of the class being
returned by the factory method does not have to be of the same type as
the class which contains the <literal>static</literal> factory method,
although in this example it is. An instance (non-static) factory
method would be used in an essentially identical fashion (aside from
the use of the <literal>factory-bean</literal> attribute instead of
the <literal>class</literal> attribute), so details will not be
discussed here.</para>
</section>
</section>
<section id="beans-factory-properties-detailed">
<title>Dependencies and configuration in detail</title>
<para>As mentioned in the previous section, bean properties and
constructor arguments can be defined as either references to other
managed beans (collaborators), or values defined inline. Spring's
XML-based configuration metadata supports a number of sub-element types
within its <literal>&lt;property/&gt;</literal> and
<literal>&lt;constructor-arg/&gt;</literal> elements for just this
purpose.</para>
<section id="beans-value-element">
<title>Straight values (primitives, <literal>Strings</literal>,
etc.)</title>
<para>The <literal>&lt;value/&gt;</literal> element specifies a
property or constructor argument as a human-readable string
representation. <link
linkend="beans-factory-collaborators-propertyeditor">As mentioned
previously</link>, JavaBeans <literal>PropertyEditors</literal> are
used to convert these string values from a
<classname>String</classname> to the actual type of the property or
argument.</para>
<programlisting language="xml">&lt;bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"&gt;
<lineannotation>&lt;!-- results in a <methodname>setDriverClassName(String)</methodname> call --&gt;</lineannotation>
&lt;property name="driverClassName"&gt;
&lt;value&gt;com.mysql.jdbc.Driver&lt;/value&gt;
&lt;/property&gt;
&lt;property name="url"&gt;
&lt;value&gt;jdbc:mysql://localhost:3306/mydb&lt;/value&gt;
&lt;/property&gt;
&lt;property name="username"&gt;
&lt;value&gt;root&lt;/value&gt;
&lt;/property&gt;
&lt;property name="password"&gt;
&lt;value&gt;masterkaoli&lt;/value&gt;
&lt;/property&gt;
&lt;/bean&gt;</programlisting>
<para>The <literal>&lt;property/&gt;</literal> and
<literal>&lt;constructor-arg/&gt;</literal> elements also support the
use of the <literal>'value'</literal> attribute, which can lead to
much more succinct configuration. When using the
<literal>'value'</literal> attribute, the above bean definition reads
like so:</para>
<programlisting language="xml">&lt;bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"&gt;
<lineannotation>&lt;!-- results in a <methodname>setDriverClassName(String)</methodname> call --&gt;</lineannotation>
&lt;property name="driverClassName" value="com.mysql.jdbc.Driver"/&gt;
&lt;property name="url" value="jdbc:mysql://localhost:3306/mydb"/&gt;
&lt;property name="username" value="root"/&gt;
&lt;property name="password" value="masterkaoli"/&gt;
&lt;/bean&gt;</programlisting>
<para>The Spring team generally prefer the attribute style over the
use of nested <literal>&lt;value/&gt;</literal> elements. If you are
reading this reference manual straight through from top to bottom
(wow!) then we are getting slightly ahead of ourselves here, but you
can also configure a <classname>java.util.Properties</classname>
instance like so:</para>
<programlisting language="xml">&lt;bean id="mappings" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"&gt;
<lineannotation>&lt;!-- typed as a <classname>java.util.Properties</classname> --&gt;</lineannotation>
&lt;property name="properties"&gt;
&lt;value&gt;
jdbc.driver.className=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mydb
&lt;/value&gt;
&lt;/property&gt;
&lt;/bean&gt;</programlisting>
<para>Can you see what is happening? The Spring container is
converting the text inside the <literal>&lt;value/&gt;</literal>
element into a <classname>java.util.Properties</classname> instance
using the JavaBeans <interfacename>PropertyEditor</interfacename>
mechanism. This is a nice shortcut, and is one of a few places where
the Spring team do favor the use of the nested
<literal>&lt;value/&gt;</literal> element over the
<literal>'value'</literal> attribute style.</para>
<section id="beans-idref-element">
<title>The <literal>idref</literal> element</title>
<para>The <literal>idref</literal> element is simply an error-proof
way to pass the <emphasis>id</emphasis> of another bean in the
container (to a <literal>&lt;constructor-arg/&gt;</literal> or
<literal>&lt;property/&gt;</literal> element).</para>
<programlisting language="xml">&lt;bean id="theTargetBean" class="..."/&gt;
&lt;bean id="theClientBean" class="..."&gt;
&lt;property name="targetName"&gt;
&lt;idref bean="theTargetBean" /&gt;
&lt;/property&gt;
&lt;/bean&gt;</programlisting>
<para>The above bean definition snippet is
<emphasis>exactly</emphasis> equivalent (at runtime) to the
following snippet:</para>
<programlisting language="xml">&lt;bean id="theTargetBean" class="..." /&gt;
&lt;bean id="client" class="..."&gt;
&lt;property name="targetName" value="theTargetBean" /&gt;
&lt;/bean&gt;</programlisting>
<para>The main reason the first form is preferable to the second is
that using the <literal>idref</literal> tag allows the container to
validate <emphasis>at deployment time</emphasis> that the
referenced, named bean actually exists. In the second variation, no
validation is performed on the value that is passed to the
<literal>'targetName'</literal> property of the
<literal>'client'</literal> bean. Any typo will only be discovered
(with most likely fatal results) when the
<literal>'client'</literal> bean is actually instantiated. If the
<literal>'client'</literal> bean is a <link
linkend="beans-factory-scopes">prototype</link> bean, this typo (and
the resulting exception) may only be discovered long after the
container is actually deployed.</para>
<para>Additionally, if the bean being referred to is in the same XML
unit, and the bean name is the bean <emphasis>id</emphasis>, the
<literal>'local'</literal> attribute may be used, which allows the
XML parser itself to validate the bean id even earlier, at XML
document parse time.</para>
<programlisting language="xml">&lt;property name="targetName"&gt;
<lineannotation>&lt;!-- a bean with an id of '<literal>theTargetBean</literal>' must exist; otherwise an XML exception will be thrown --&gt;</lineannotation>
&lt;idref local="theTargetBean"/&gt;
&lt;/property&gt;</programlisting>
<para>By way of an example, one common place (at least in pre-Spring
2.0 configuration) where the &lt;idref/&gt; element brings value is
in the configuration of <link linkend="aop-pfb-1">AOP
interceptors</link> in a <classname>ProxyFactoryBean</classname>
bean definition. If you use &lt;idref/&gt; elements when specifying
the interceptor names, there is no chance of inadvertently
misspelling an interceptor id.</para>
</section>
</section>
<section id="beans-ref-element">
<title>References to other beans (collaborators)</title>
<para>The <literal>ref</literal> element is the final element allowed
inside a <literal>&lt;constructor-arg/&gt;</literal> or
<literal>&lt;property/&gt;</literal> definition element. It is used to
set the value of the specified property to be a reference to another
bean managed by the container (a collaborator). As mentioned in a
previous section, the referred-to bean is considered to be a
dependency of the bean who's property is being set, and will be
initialized on demand as needed (if it is a singleton bean it may have
already been initialized by the container) before the property is set.
All references are ultimately just a reference to another object, but
there are 3 variations on how the id/name of the other object may be
specified, which determines how scoping and validation is
handled.</para>
<para>Specifying the target bean by using the <literal>bean</literal>
attribute of the <literal>&lt;ref/&gt;</literal> tag is the most
general form, and will allow creating a reference to any bean in the
same container (whether or not in the same XML file), or parent
container. The value of the <literal>'bean'</literal> attribute may be
the same as either the <literal>'id'</literal> attribute of the target
bean, or one of the values in the <literal>'name'</literal> attribute
of the target bean.</para>
<programlisting language="xml">&lt;ref bean="someBean"/&gt;</programlisting>
<para>Specifying the target bean by using the <literal>local</literal>
attribute leverages the ability of the XML parser to validate XML id
references within the same file. The value of the
<literal>local</literal> attribute must be the same as the
<literal>id</literal> attribute of the target bean. The XML parser
will issue an error if no matching element is found in the same file.
As such, using the local variant is the best choice (in order to know
about errors as early as possible) if the target bean is in the same
XML file.</para>
<programlisting language="xml">&lt;ref local="someBean"/&gt;</programlisting>
<para>Specifying the target bean by using the
<literal>'parent'</literal> attribute allows a reference to be created
to a bean which is in a parent container of the current container. The
value of the <literal>'parent'</literal> attribute may be the same as
either the <literal>'id'</literal> attribute of the target bean, or
one of the values in the <literal>'name'</literal> attribute of the
target bean, and the target bean must be in a parent container to the
current one. The main use of this bean reference variant is when you
have a hierarchy of containers and you want to wrap an existing bean
in a parent container with some sort of proxy which will have the same
name as the parent bean.</para>
<programlisting language="xml"><lineannotation>&lt;!-- in the parent context --&gt;</lineannotation>
&lt;bean id="accountService" class="com.foo.SimpleAccountService"&gt;
<lineannotation>&lt;!-- insert dependencies as required as here --&gt;</lineannotation>
&lt;/bean&gt;</programlisting>
<programlisting language="xml"><lineannotation>&lt;!-- in the child (descendant) context --&gt;</lineannotation>
&lt;bean id="accountService" <lineannotation>&lt;-- notice that the name of this bean is the <emphasis
role="bold">same</emphasis> as the name of the <literal>'parent'</literal> bean</lineannotation>
class="org.springframework.aop.framework.ProxyFactoryBean"&gt;
&lt;property name="target"&gt;
&lt;ref parent="accountService"/&gt; <lineannotation>&lt;-- notice how we refer to the <emphasis
role="bold">parent</emphasis> bean</lineannotation>
&lt;/property&gt;
<lineannotation>&lt;!-- insert other configuration and dependencies as required as here --&gt;</lineannotation>
&lt;/bean&gt;</programlisting>
</section>
<section id="beans-inner-beans">
<title>Inner beans</title>
<para>A <literal>&lt;bean/&gt;</literal> element inside the
<literal>&lt;property/&gt;</literal> or
<literal>&lt;constructor-arg/&gt;</literal> elements is used to define
a so-called <firstterm>inner bean</firstterm>. An inner bean
definition does not need to have any id or name defined, and it is
best not to even specify any id or name value because the id or name
value simply will be ignored by the container.</para>
<programlisting language="xml">&lt;bean id="outer" class="..."&gt;
<lineannotation>&lt;!-- instead of using a reference to a target bean, simply define the target bean inline --&gt;</lineannotation>
&lt;property name="target"&gt;
&lt;bean class="com.example.Person"&gt; <lineannotation>&lt;!-- this is the inner bean --&gt;</lineannotation>
&lt;property name="name" value="Fiona Apple"/&gt;
&lt;property name="age" value="25"/&gt;
&lt;/bean&gt;
&lt;/property&gt;
&lt;/bean&gt;</programlisting>
<para>Note that in the specific case of inner beans, the
<literal>'scope'</literal> flag and any <literal>'id'</literal> or
<literal>'name'</literal> attribute are effectively ignored. Inner
beans are <emphasis>always</emphasis> anonymous and they are
<emphasis>always</emphasis> scoped as <link
linkend="beans-factory-scopes-prototype">prototypes</link>. Please
also note that it is <emphasis>not</emphasis> possible to inject inner
beans into collaborating beans other than the enclosing bean.</para>
</section>
<section id="beans-collection-elements">
<title>Collections</title>
<para>The <literal>&lt;list/&gt;</literal>,
<literal>&lt;set/&gt;</literal>, <literal>&lt;map/&gt;</literal>, and
<literal>&lt;props/&gt;</literal> elements allow properties and
arguments of the Java <interfacename>Collection</interfacename> type
<interfacename>List</interfacename>,
<interfacename>Set</interfacename>,
<interfacename>Map</interfacename>, and
<interfacename>Properties</interfacename>, respectively, to be defined
and set.</para>
<programlisting language="xml">&lt;bean id="moreComplexObject" class="example.ComplexObject"&gt;
<lineannotation>&lt;!-- results in a setAdminEmails(<classname>java.util.Properties</classname>) call --&gt;</lineannotation>
&lt;property name="adminEmails"&gt;
&lt;props&gt;
&lt;prop key="administrator"&gt;administrator@example.org&lt;/prop&gt;
&lt;prop key="support"&gt;support@example.org&lt;/prop&gt;
&lt;prop key="development"&gt;development@example.org&lt;/prop&gt;
&lt;/props&gt;
&lt;/property&gt;
<lineannotation>&lt;!-- results in a setSomeList(<interfacename>java.util.List</interfacename>) call --&gt;</lineannotation>
&lt;property name="someList"&gt;
&lt;list&gt;
&lt;value&gt;a list element followed by a reference&lt;/value&gt;
&lt;ref bean="myDataSource" /&gt;
&lt;/list&gt;
&lt;/property&gt;
<lineannotation>&lt;!-- results in a setSomeMap(<interfacename>java.util.Map</interfacename>) call --&gt;</lineannotation>
&lt;property name="someMap"&gt;
&lt;map&gt;
&lt;entry&gt;
&lt;key&gt;
&lt;value&gt;an entry&lt;/value&gt;
&lt;/key&gt;
&lt;value&gt;just some string&lt;/value&gt;
&lt;/entry&gt;
&lt;entry&gt;
&lt;key&gt;
&lt;value&gt;a ref&lt;/value&gt;
&lt;/key&gt;
&lt;ref bean="myDataSource" /&gt;
&lt;/entry&gt;
&lt;/map&gt;
&lt;/property&gt;
<lineannotation>&lt;!-- results in a setSomeSet(java.util.Set) call --&gt;</lineannotation>
&lt;property name="someSet"&gt;
&lt;set&gt;
&lt;value&gt;just some string&lt;/value&gt;
&lt;ref bean="myDataSource" /&gt;
&lt;/set&gt;
&lt;/property&gt;
&lt;/bean&gt;</programlisting>
<note>
<para>The nested element style used this initial example tends to
become quite verbose. Fortunately, there are attribute shortcuts for
most elements, which you can read about in <xref
linkend="xml-config-shortcuts" />.</para>
</note>
<para><emphasis>Note that the value of a map key or value, or a set
value, can also again be any of the following
elements:</emphasis></para>
<programlisting language="xml">bean | ref | idref | list | set | map | props | value | null</programlisting>
<section id="beans-collection-elements-merging">
<title>Collection merging</title>
<para>As of Spring 2.0, the container also supports the
<emphasis>merging</emphasis> of collections. This allows an
application developer to define a parent-style
<literal>&lt;list/&gt;</literal>, <literal>&lt;map/&gt;</literal>,
<literal>&lt;set/&gt;</literal> or <literal>&lt;props/&gt;</literal>
element, and have child-style <literal>&lt;list/&gt;</literal>,
<literal>&lt;map/&gt;</literal>, <literal>&lt;set/&gt;</literal> or
<literal>&lt;props/&gt;</literal> elements inherit and override
values from the parent collection; that is to say the child
collection's values will be the result obtained from the merging of
the elements of the parent and child collections, with the child's
collection elements overriding values specified in the parent
collection.</para>
<para><emphasis>Please note that this section on merging makes use
of the parent-child bean mechanism. This concept has not yet been
introduced, so readers unfamiliar with the concept of parent and
child bean definitions may wish to read the <link
linkend="beans-child-bean-definitions">relevant section</link>
before continuing.</emphasis></para>
<para>Find below an example of the collection merging
feature:</para>
<programlisting language="xml">&lt;beans&gt;
&lt;bean id="parent" abstract="true" class="example.ComplexObject"&gt;
&lt;property name="adminEmails"&gt;
&lt;props&gt;
&lt;prop key="administrator"&gt;administrator@example.com&lt;/prop&gt;
&lt;prop key="support"&gt;support@example.com&lt;/prop&gt;
&lt;/props&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;bean id="child" parent="parent"&gt;
&lt;property name="adminEmails"&gt;
<lineannotation>&lt;!-- the merge is specified on the *child* collection definition --&gt;</lineannotation>
&lt;props merge="true"&gt;
&lt;prop key="sales"&gt;sales@example.com&lt;/prop&gt;
&lt;prop key="support"&gt;support@example.co.uk&lt;/prop&gt;
&lt;/props&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;beans&gt;</programlisting>
<para>Notice the use of the <literal>merge=true</literal> attribute
on the <literal>&lt;props/&gt;</literal> element of the
<literal>adminEmails</literal> property of the
<literal>child</literal> bean definition. When the
<literal>child</literal> bean is actually resolved and instantiated
by the container, the resulting instance will have an
<literal>adminEmails</literal> <classname>Properties</classname>
collection that contains the result of the merging of the child's
<literal>adminEmails</literal> collection with the parent's
<literal>adminEmails</literal> collection.</para>
<programlisting>administrator=administrator@example.com
sales=sales@example.com
support=support@example.co.uk</programlisting>
<para>Notice how the child <classname>Properties</classname>
collection's value set will have inherited all the property elements
from the parent <literal>&lt;props/&gt;</literal>. Notice also how
the child's value for the <literal>support</literal> value overrides
the value in the parent collection.</para>
<para>This merging behavior applies similarly to the
<literal>&lt;list/&gt;</literal>, <literal>&lt;map/&gt;</literal>,
and <literal>&lt;set/&gt;</literal> collection types. In the
specific case of the <literal>&lt;list/&gt;</literal> element, the
semantics associated with the <classname>List</classname> collection
type, that is the notion of an <literal>ordered</literal> collection
of values, is maintained; the parent's values will precede all of
the child list's values. In the case of the
<interfacename>Map</interfacename>,
<interfacename>Set</interfacename>, and
<interfacename>Properties</interfacename> collection types, there is
no notion of ordering and hence no ordering semantics are in effect
for the collection types that underlie the associated
<interfacename>Map</interfacename>,
<interfacename>Set</interfacename> and
<interfacename>Properties</interfacename> implementation types used
internally by the container.</para>
<para>Finally, some minor notes about the merging support are in
order; you cannot merge different collection types (e.g. a
<interfacename>Map</interfacename> and a
<interfacename>List</interfacename>), and if you do attempt to do so
an appropriate <classname>Exception</classname> will be thrown; and
in case it is not immediately obvious, the
<literal>'merge'</literal> attribute must be specified on the lower
level, inherited, child definition; specifying the
<literal>'merge'</literal> attribute on a parent collection
definition is redundant and will not result in the desired merging;
and (lastly), please note that this merging feature is only
available in Spring 2.0 (and later versions).</para>
</section>
<section id="beans-collection-elements-strongly-typed">
<title>Strongly-typed collection (Java 5+ only)</title>
<para>If you are using Java 5 or Java 6, you will be aware that it
is possible to have strongly typed collections (using generic
types). That is, it is possible to declare a
<interfacename>Collection</interfacename> type such that it can only
contain <classname>String</classname> elements (for example). If you
are using Spring to dependency inject a strongly-typed
<interfacename>Collection</interfacename> into a bean, you can take
advantage of Spring's type-conversion support such that the elements
of your strongly-typed <interfacename>Collection</interfacename>
instances will be converted to the appropriate type prior to being
added to the <interfacename>Collection</interfacename>.</para>
<programlisting language="java">public class Foo {
private Map&lt;String, Float&gt; accounts;
public void setAccounts(Map&lt;String, Float&gt; accounts) {
this.accounts = accounts;
}
}</programlisting>
<programlisting language="xml">&lt;beans&gt;
&lt;bean id="foo" class="x.y.Foo"&gt;
&lt;property name="accounts"&gt;
&lt;map&gt;
&lt;entry key="one" value="9.99"/&gt;
&lt;entry key="two" value="2.75"/&gt;
&lt;entry key="six" value="3.99"/&gt;
&lt;/map&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;/beans&gt;</programlisting>
<para>When the <literal>'accounts'</literal> property of the
<literal>'foo'</literal> bean is being prepared for injection, the
generics information about the element type of the strongly-typed
<classname>Map&lt;String, Float&gt;</classname> is actually
available via reflection, and so Spring's type conversion
infrastructure will actually recognize the various value elements as
being of type <classname>Float</classname> and so the string values
<literal>'9.99', '2.75'</literal>, and <literal>'3.99'</literal>
will be converted into an actual <classname>Float</classname>
type.</para>
</section>
</section>
<section id="beans-null-element">
<title><literal>Nulls</literal></title>
<para>The <literal>&lt;null/&gt;</literal> element is used to handle
<literal>null</literal> values. Spring treats empty arguments for
properties and the like as empty <literal>Strings</literal>. The
following XML-based configuration metadata snippet results in the
email property being set to the empty <classname>String</classname>
value ("")</para>
<programlisting language="xml">&lt;bean class="ExampleBean"&gt;
&lt;property name="email"&gt;&lt;value/&gt;&lt;/property&gt;
&lt;/bean&gt;</programlisting>
<para>This is equivalent to the following Java code:
<methodname>exampleBean.setEmail("")</methodname>. The special
<literal>&lt;null&gt;</literal> element may be used to indicate a
<literal>null</literal> value. For example:</para>
<programlisting language="xml">&lt;bean class="ExampleBean"&gt;
&lt;property name="email"&gt;&lt;null/&gt;&lt;/property&gt;
&lt;/bean&gt;</programlisting>
<para>The above configuration is equivalent to the following Java
code: <methodname>exampleBean.setEmail(null)</methodname>.</para>
</section>
<section id="xml-config-shortcuts">
<title>Shortcuts and other convenience options for XML-based
configuration metadata</title>
<para>The configuration metadata shown so far is a tad verbose. That
is why there are several options available for you to limit the amount
of XML you have to write to configure your components. The first is a
shortcut to define values and references to other beans as part of a
<literal>&lt;property/&gt;</literal> definition. The second is
slightly different format of specifying properties altogether.</para>
<section id="beans-value-ref-shortcuts">
<title>XML-based configuration metadata shortcuts</title>
<para>The <literal>&lt;property/&gt;</literal>,
<literal>&lt;constructor-arg/&gt;</literal>, and
<literal>&lt;entry/&gt;</literal> elements all support a
<literal>'value'</literal> attribute which may be used instead of
embedding a full <literal>&lt;value/&gt;</literal> element.
Therefore, the following:</para>
<programlisting language="xml">&lt;property name="myProperty"&gt;
&lt;value&gt;hello&lt;/value&gt;
&lt;/property&gt;</programlisting>
<programlisting language="xml">&lt;constructor-arg&gt;
&lt;value&gt;hello&lt;/value&gt;
&lt;/constructor-arg&gt;</programlisting>
<programlisting language="xml">&lt;entry key="myKey"&gt;
&lt;value&gt;hello&lt;/value&gt;
&lt;/entry&gt;</programlisting>
<para>are equivalent to:</para>
<programlisting language="xml">&lt;property name="myProperty" value="hello"/&gt;</programlisting>
<programlisting language="xml">&lt;constructor-arg value="hello"/&gt;</programlisting>
<programlisting language="xml">&lt;entry key="myKey" value="hello"/&gt;</programlisting>
<para>The <literal>&lt;property/&gt;</literal> and
<literal>&lt;constructor-arg/&gt;</literal> elements support a
similar shortcut <literal>'ref'</literal> attribute which may be
used instead of a full nested <literal>&lt;ref/&gt;</literal>
element. Therefore, the following:</para>
<programlisting language="xml">&lt;property name="myProperty"&gt;
&lt;ref bean="myBean"&gt;
&lt;/property&gt;</programlisting>
<programlisting language="xml">&lt;constructor-arg&gt;
&lt;ref bean="myBean"&gt;
&lt;/constructor-arg&gt;</programlisting>
<para>... are equivalent to:</para>
<programlisting language="xml">&lt;property name="myProperty" ref="myBean"/&gt;</programlisting>
<programlisting language="xml">&lt;constructor-arg ref="myBean"/&gt;</programlisting>
<para>Note however that the shortcut form is equivalent to a
<literal>&lt;ref bean="xxx"&gt;</literal> element; there is no
shortcut for <literal>&lt;ref local="xxx"</literal>&gt;. To enforce
a strict local reference, you must use the long form.</para>
<para>Finally, the entry element allows a shortcut form to specify
the key and/or value of the map, in the form of the
<literal>'key'</literal> / <literal>'key-ref'</literal> and
<literal>'value'</literal> / <literal>'value-ref'</literal>
attributes. Therefore, the following:</para>
<programlisting language="xml">&lt;entry&gt;
&lt;key&gt;
&lt;ref bean="myKeyBean" /&gt;
&lt;/key&gt;
&lt;ref bean="myValueBean" /&gt;
&lt;/entry&gt;</programlisting>
<para>is equivalent to:</para>
<programlisting language="xml">&lt;entry key-ref="myKeyBean" value-ref="myValueBean"/&gt;</programlisting>
<para>Again, the shortcut form is equivalent to a <literal>&lt;ref
bean="xxx"&gt;</literal> element; there is no shortcut for
<literal>&lt;ref local="xxx"</literal>&gt;.</para>
</section>
<section id="beans-p-namespace">
<title>The p-namespace and how to use it to configure
properties</title>
<para>The second option you have to limit the amount of XML you have
to write to configure your components is to use the special
"p-namespace". Spring 2.0 and later features support for extensible
configuration formats <link linkend="xsd-config">using
namespaces</link>. Those namespaces are all based on an XML Schema
definition. In fact, the <literal>beans</literal> configuration
format that you've been reading about is defined in an XML Schema
document.</para>
<para>One special namespace is not defined in an XSD file, and only
exists in the core of Spring itself. The so-called p-namespace
doesn't need a schema definition and is an alternative way of
configuring your properties differently than the way you have seen
so far. Instead of using nested <literal>&lt;property/&gt;</literal>
elements, using the p-namespace you can use attributes as part of
the <literal>bean</literal> element that describe your property
values. The values of the attributes will be taken as the values for
your properties.</para>
<para>The following two XML snippets boil down to the same thing in
the end: the first is using the standard XML format whereas the
second example is using the p-namespace.</para>
<programlisting language="xml">&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"&gt;
&lt;bean name="classic" class="com.example.ExampleBean"&gt;
&lt;property name="email" value="foo@bar.com"/&gt;
&lt;/bean&gt;
&lt;bean name="p-namespace" class="com.example.ExampleBean"
p:email="foo@bar.com"/&gt;
&lt;/beans&gt;</programlisting>
<para>As you can see, we are including an attribute in the
p-namespace called email in the bean definition - this is telling
Spring that it should include a property declaration. As previously
mentioned, the p-namespace doesn't have a schema definition, so the
name of the attribute can be set to whatever name your property
has.</para>
<para>This next example includes two more bean definitions that both
have a reference to another bean:</para>
<programlisting language="xml">&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"&gt;
&lt;bean name="john-classic" class="com.example.Person"&gt;
&lt;property name="name" value="John Doe"/&gt;
&lt;property name="spouse" ref="jane"/&gt;
&lt;/bean&gt;
&lt;bean name="john-modern"
class="com.example.Person"
p:name="John Doe"
p:spouse-ref="jane"/&gt;
&lt;bean name="jane" class="com.example.Person"&gt;
&lt;property name="name" value="Jane Doe"/&gt;
&lt;/bean&gt;
&lt;/beans&gt;</programlisting>
<para>As you can see, this example doesn't only include a property
value using the p-namespace, but also uses a special format to
declare property references. Whereas the first bean definition uses
<literal>&lt;property name="spouse" ref="jane"/&gt;</literal> to
create a reference from bean <literal>john</literal> to bean
<literal>jane</literal>, the second bean definition uses
<literal>p:spouse-ref="jane"</literal> as an attribute to do the
exact same thing. In this case '<literal>spouse</literal>' is the
property name whereas the '<literal>-ref</literal>' part indicates
that this is not a straight value but rather a reference to another
bean.</para>
<note>
<para>Please note that the p-namespace is not quite as flexible as
the standard XML format - for example particular, the 'special'
format used to declare property references will clash with
properties that end in '<literal>Ref</literal>', whereas the
standard XML format would have no problem there. We recommend that
you choose carefully which approach you are going to use in your
projects. You should also communicate this to your team members so
you won't end up with XML documents using all three approaches at
the same time. This will prevent people from not understanding the
application because of different ways of configuring it, and will
add to the overall consistency of your codebase.</para>
</note>
</section>
</section>
<section id="beans-compound-property-names">
<title>Compound property names</title>
<para>Compound or nested property names are perfectly legal when
setting bean properties, as long as all components of the path except
the final property name are not <literal>null</literal>. Consider the
following bean definition...</para>
<programlisting language="xml">&lt;bean id="foo" class="foo.Bar"&gt;
&lt;property name="fred.bob.sammy" value="123" /&gt;
&lt;/bean&gt;</programlisting>
<para>The <literal>foo</literal> bean has a <literal>fred</literal>
property which has a <literal>bob</literal> property, which has a
<literal>sammy</literal> property, and that final
<literal>sammy</literal> property is being set to the value
<literal>123</literal>. In order for this to work, the
<literal>fred</literal> property of <literal>foo</literal>, and the
<literal>bob</literal> property of <literal>fred</literal> must not be
<literal>null</literal> be non-null after the bean is constructed, or
a <exceptionname>NullPointerException</exceptionname> will be
thrown.</para>
</section>
</section>
<section id="beans-factory-dependson">
<title>Using <literal>depends-on</literal></title>
<para>For most situations, the fact that a bean is a dependency of
another is expressed by the fact that one bean is set as a property of
another. This is typically accomplished with the <link
linkend="beans-ref-element"><literal>&lt;ref/&gt;</literal>
element</link> in XML-based configuration metadata. For the relatively
infrequent situations where dependencies between beans are less direct
(for example, when a static initializer in a class needs to be
triggered, such as database driver registration), the
<literal>'depends-on'</literal> attribute may be used to explicitly
force one or more beans to be initialized before the bean using this
element is initialized. Find below an example of using the
<literal>'depends-on'</literal> attribute to express a dependency on a
single bean.</para>
<programlisting language="xml">&lt;bean id="beanOne" class="ExampleBean" depends-on="<emphasis
role="bold">manager</emphasis>"/&gt;
&lt;bean id="<emphasis role="bold">manager</emphasis>" class="ManagerBean" /&gt;</programlisting>
<para>If you need to express a dependency on multiple beans, you can
supply a list of bean names as the value of the
<literal>'depends-on'</literal> attribute, with commas, whitespace and
semicolons all valid delimiters, like so:</para>
<programlisting language="xml">&lt;bean id="beanOne" class="ExampleBean" depends-on="manager,accountDao"&gt;
&lt;property name="manager" ref="manager" /&gt;
&lt;/bean&gt;
&lt;bean id="manager" class="ManagerBean" /&gt;
&lt;bean id="accountDao" class="x.y.jdbc.JdbcAccountDao" /&gt;</programlisting>
<note>
<para>The '<literal>depends-on</literal>' attribute at the bean
definition level is used not only to specify an initialization time
dependency, but also to specify the corresponding destroy time
dependency (in the case of <link
linkend="beans-factory-scopes-singleton">singleton</link> beans only).
Dependent beans that define a '<literal>depends-on</literal>'
relationship with a given bean will be destroyed first - prior to the
given bean itself being destroyed. As a consequence,
'<literal>depends-on</literal>' may be used to control shutdown order
too.</para>
</note>
</section>
<section id="beans-factory-lazy-init">
<title>Lazily-instantiated beans</title>
<para>The default behavior for
<interfacename>ApplicationContext</interfacename> implementations is to
eagerly pre-instantiate all <literal>singleton</literal> beans at
startup. Pre-instantiation means that an
<interfacename>ApplicationContext</interfacename> will eagerly create
and configure all of its <link
linkend="beans-factory-scopes-singleton">singleton</link> beans as part
of its initialization process. Generally this is <emphasis>a good
thing</emphasis>, because it means that any errors in the configuration
or in the surrounding environment will be discovered immediately (as
opposed to possibly hours or even days down the line).</para>
<para>However, there are times when this behavior is
<emphasis>not</emphasis> what is wanted. If you do not want a singleton
bean to be pre-instantiated when using an
<interfacename>ApplicationContext</interfacename>, you can selectively
control this by marking a bean definition as lazy-initialized. A
lazily-initialized bean indicates to the IoC container whether or not a
bean instance should be created at startup or when it is first
requested.</para>
<para>When configuring beans via XML, this lazy loading is controlled by
the <literal>'lazy-init'</literal> attribute on the
<literal>&lt;bean/&gt;</literal> element; for example:</para>
<programlisting language="xml">&lt;bean id="lazy" class="com.foo.ExpensiveToCreateBean" <emphasis
role="bold">lazy-init="true"</emphasis>/&gt;
&lt;bean name="not.lazy" class="com.foo.AnotherBean"/&gt;</programlisting>
<para>When the above configuration is consumed by an
<interfacename>ApplicationContext</interfacename>, the bean named
<literal>'lazy'</literal> will <emphasis>not</emphasis> be eagerly
pre-instantiated when the
<interfacename>ApplicationContext</interfacename> is starting up,
whereas the <literal>'not.lazy'</literal> bean will be eagerly
pre-instantiated.</para>
<para>One thing to understand about lazy-initialization is that even
though a bean definition may be marked up as being lazy-initialized, if
the lazy-initialized bean is the dependency of a singleton bean that is
not lazy-initialized, when the
<interfacename>ApplicationContext</interfacename> is eagerly
pre-instantiating the singleton, it will have to satisfy all of the
singletons dependencies, one of which will be the lazy-initialized bean!
So don't be confused if the IoC container creates one of the beans that
you have explicitly configured as lazy-initialized at startup; all that
means is that the lazy-initialized bean is being injected into a
non-lazy-initialized singleton bean elsewhere.</para>
<para>It is also possible to control lazy-initialization at the
container level by using the <literal>'default-lazy-init'</literal>
attribute on the <literal>&lt;beans/&gt;</literal> element; for
example:</para>
<programlisting language="xml">&lt;beans default-lazy-init="true"&gt;
<lineannotation>&lt;!-- no beans will be pre-instantiated... --&gt;</lineannotation>
&lt;/beans&gt;</programlisting>
</section>
<section id="beans-factory-autowire">
<title>Autowiring collaborators</title>
<para>The Spring container is able to <emphasis>autowire</emphasis>
relationships between collaborating beans. This means that it is
possible to automatically let Spring resolve collaborators (other beans)
for your bean by inspecting the contents of the
<interfacename>BeanFactory</interfacename>. The autowiring functionality
has five modes. Autowiring is specified <emphasis>per</emphasis> bean
and can thus be enabled for some beans, while other beans will not be
autowired. Using autowiring, it is possible to reduce or eliminate the
need to specify properties or constructor arguments, thus saving a
significant amount of typing. <footnote>
<para>See the section entitled <xref
linkend="beans-factory-collaborators" /></para>
</footnote> When using XML-based configuration metadata, the autowire
mode for a bean definition is specified by using the
<literal>autowire</literal> attribute of the
<literal>&lt;bean/&gt;</literal> element. The following values are
allowed:</para>
<table id="beans-factory-autowiring-modes-tbl">
<title>Autowiring modes</title>
<tgroup cols="2">
<colspec colname="c1" colwidth="1*" />
<colspec colname="c2" colwidth="5*" />
<thead>
<row>
<entry>Mode</entry>
<entry>Explanation</entry>
</row>
</thead>
<tbody>
<row>
<entry>no</entry>
<entry><para>No autowiring at all. Bean references must be
defined via a <literal>ref</literal> element. This is the
default, and changing this is discouraged for larger
deployments, since explicitly specifying collaborators gives
greater control and clarity. To some extent, it is a form of
documentation about the structure of a system.</para></entry>
</row>
<row>
<entry>byName</entry>
<entry><para>Autowiring by property name. This option will
inspect the container and look for a bean named exactly the same
as the property which needs to be autowired. For example, if you
have a bean definition which is set to autowire by name, and it
contains a <emphasis>master</emphasis> property (that is, it has
a <emphasis>setMaster(..)</emphasis> method), Spring will look
for a bean definition named <literal>master</literal>, and use
it to set the property.</para></entry>
</row>
<row>
<entry>byType</entry>
<entry><para>Allows a property to be autowired if there is
exactly one bean of the property type in the container. If there
is more than one, a fatal exception is thrown, and this
indicates that you may not use <emphasis>byType</emphasis>
autowiring for that bean. If there are no matching beans,
nothing happens; the property is not set. If this is not
desirable, setting the
<literal>dependency-check="objects"</literal> attribute value
specifies that an error should be thrown in this
case.</para></entry>
</row>
<row>
<entry>constructor</entry>
<entry><para>This is analogous to <emphasis>byType</emphasis>,
but applies to constructor arguments. If there isn't exactly one
bean of the constructor argument type in the container, a fatal
error is raised.</para></entry>
</row>
<row>
<entry>autodetect</entry>
<entry><para>Chooses <emphasis>constructor</emphasis> or
<emphasis>byType</emphasis> through introspection of the bean
class. If a default constructor is found, the
<emphasis>byType</emphasis> mode will be applied.</para></entry>
</row>
</tbody>
</tgroup>
</table>
<para>Note that explicit dependencies in <literal>property</literal> and
<literal>constructor-arg</literal> settings
<interfacename>always</interfacename> override autowiring. Please also
note that it is not currently possible to autowire so-called
<emphasis>simple</emphasis> properties such as primitives,
<classname>Strings</classname>, and <classname>Classes</classname> (and
arrays of such simple properties). (This is by-design and should be
considered a <emphasis>feature</emphasis>.) When using either the
<emphasis>byType</emphasis> or <emphasis>constructor</emphasis>
autowiring mode, it is possible to wire arrays and typed-collections. In
such cases <emphasis>all</emphasis> autowire candidates within the
container that match the expected type will be provided to satisfy the
dependency. Strongly-typed Maps can even be autowired if the expected
key type is <classname>String</classname>. An autowired Map's values
will consist of all bean instances that match the expected type, and the
Map's keys will contain the corresponding bean names.</para>
<para>Autowire behavior can be combined with dependency checking, which
will be performed after all autowiring has been completed.</para>
<para>It is important to understand the various advantages and
disadvantages of autowiring. Some advantages of autowiring
include:</para>
<itemizedlist>
<listitem>
<para>Autowiring can significantly reduce the volume of
configuration required. However, mechanisms such as the use of a
bean template (<link
linkend="beans-child-bean-definitions">discussed elsewhere in this
chapter</link>) are also valuable in this regard.</para>
</listitem>
<listitem>
<para>Autowiring can cause configuration to keep itself up to date
as your objects evolve. For example, if you need to add an
additional dependency to a class, that dependency can be satisfied
automatically without the need to modify configuration. Thus there
may be a strong case for autowiring during development, without
ruling out the option of switching to explicit wiring when the code
base becomes more stable.</para>
</listitem>
</itemizedlist>
<para>Some disadvantages of autowiring:</para>
<itemizedlist>
<listitem>
<para>Autowiring is more magical than explicit wiring. Although, as
noted in the above table, Spring is careful to avoid guessing in
case of ambiguity which might have unexpected results, the
relationships between your Spring-managed objects are no longer
documented explicitly.</para>
</listitem>
<listitem>
<para>Wiring information may not be available to tools that may
generate documentation from a Spring container.</para>
</listitem>
</itemizedlist>
<para>Another issue to consider when autowiring by type is that multiple
bean definitions within the container may match the type specified by
the setter method or constructor argument to be autowired. For arrays,
collections, or Maps, this is not necessarily a problem. However for
dependencies that expect a single value, this ambiguity will not be
arbitrarily resolved. Instead, if no unique bean definition is
available, an Exception will be thrown. You do have several options when
confronted with this scenario. First, you may abandon autowiring in
favor of explicit wiring. Second, you may designate that certain bean
definitions are never to be considered as candidates by setting their
<literal>'autowire-candidate'</literal> attributes to
<literal>'false'</literal> as described in the next section. Third, you
may designate a single bean definition as the
<emphasis>primary</emphasis> candidate by setting the
<literal>'primary'</literal> attribute of its
<literal>&lt;bean/&gt;</literal> element to <literal>'true'</literal>.
Finally, if you are using at least Java 5, you may be interested in
exploring the more fine-grained control available with annotation-based
configuration as described in the section entitled <xref
linkend="beans-annotation-config" />.</para>
<para>When deciding whether to use autowiring, there is no wrong or
right answer in all cases. A degree of consistency across a project is
best though; for example, if autowiring is not used in general, it might
be confusing to developers to use it just to wire one or two bean
definitions.</para>
<section id="beans-factory-autowire-candidate">
<title>Excluding a bean from being available for autowiring</title>
<para>You can also (on a per-bean basis) totally exclude a bean from
being an autowire candidate. When configuring beans using Spring's XML
format, the <literal>'autowire-candidate'</literal> attribute of the
<literal>&lt;bean/&gt;</literal> element can be set to
<literal>'false'</literal>; this has the effect of making the
container totally exclude that specific bean definition from being
available to the autowiring infrastructure.</para>
<para>Another option is to limit autowire candidates based on
pattern-matching against bean names. The top-level
<literal>&lt;beans/&gt;</literal> element accepts one or more patterns
within its <literal>'default-autowire-candidates'</literal> attribute.
For example, to limit autowire candidate status to any bean whose name
ends with <emphasis>'Repository'</emphasis>, provide a value of
'*Repository'. To provide multiple patterns, define them in a
comma-separated list. Note that an explicit value of
<literal>'true'</literal> or <literal>'false'</literal> for a bean
definition's <literal>'autowire-candidate'</literal> attribute always
takes precedence, and for such beans, the pattern matching rules will
not apply.</para>
<para>These techniques can be useful when you have one or more beans
that you absolutely never ever want to have injected into other beans
via autowiring. It does not mean that an excluded bean cannot itself
be configured using autowiring... it can, it is rather that it itself
will not be considered as a candidate for autowiring other
beans.</para>
</section>
</section>
<section id="beans-factory-dependencies">
<title>Checking for dependencies</title>
<para>The Spring IoC container also has the ability to check for the
existence of unresolved dependencies of a bean deployed into the
container. These are JavaBeans properties of the bean, which do not have
actual values set for them in the bean definition, or alternately
provided automatically by the autowiring feature.</para>
<para>This feature is sometimes useful when you want to ensure that all
properties (or all properties of a certain type) are set on a bean. Of
course, in many cases a bean class will have default values for many
properties, or some properties do not apply to all usage scenarios, so
this feature is of limited use. Dependency checking can also be enabled
and disabled per bean, just as with the autowiring functionality. The
default is to <emphasis>not</emphasis> check dependencies. Dependency
checking can be handled in several different modes. When using XML-based
configuration metadata, this is specified via the
<literal>'dependency-check'</literal> attribute in a bean definition,
which may have the following values.</para>
<table id="beans-factory-dependency-check-modes-tbl">
<title>Dependency checking modes</title>
<tgroup cols="2">
<colspec colname="c1" colwidth="1*" />
<colspec colname="c2" colwidth="5*" />
<thead>
<row>
<entry>Mode</entry>
<entry>Explanation</entry>
</row>
</thead>
<tbody>
<row>
<entry>none</entry>
<entry><para>No dependency checking. Properties of the bean
which have no value specified for them are simply not
set.</para></entry>
</row>
<row>
<entry>simple</entry>
<entry><para>Dependency checking is performed for primitive
types and collections (everything except
collaborators).</para></entry>
</row>
<row>
<entry>object</entry>
<entry><para>Dependency checking is performed for collaborators
only.</para></entry>
</row>
<row>
<entry>all</entry>
<entry><para>Dependency checking is done for collaborators,
primitive types and collections.</para></entry>
</row>
</tbody>
</tgroup>
</table>
<para>If you are using Java 5 and thus have access to source-level
annotations, you may find the section entitled <xref
linkend="metadata-annotations-required" /> to be of interest.</para>
</section>
<section id="beans-factory-method-injection">
<title>Method Injection</title>
<para>For most application scenarios, the majority of the beans in the
container will be <link
linkend="beans-factory-scopes-singleton">singletons</link>. When a
singleton bean needs to collaborate with another singleton bean, or a
non-singleton bean needs to collaborate with another non-singleton bean,
the typical and common approach of handling this dependency by defining
one bean to be a property of the other is quite adequate. There is a
problem when the bean lifecycles are different. Consider a singleton
bean A which needs to use a non-singleton (prototype) bean B, perhaps on
each method invocation on A. The container will only create the
singleton bean A once, and thus only get the opportunity to set the
properties once. There is no opportunity for the container to provide
bean A with a new instance of bean B every time one is needed.</para>
<para>One solution to this issue is to forego some inversion of control.
Bean A can be <link linkend="beans-factory-aware-beanfactoryaware">made
aware of the container</link> by implementing the
<interfacename>BeanFactoryAware</interfacename> interface, and <link
linkend="beans-factory-client">use programmatic means</link> to ask the
container via a <methodname>getBean("B")</methodname> call for (a
typically new) bean B instance every time it needs it. Find below an
admittedly somewhat contrived example of this approach:</para>
<programlisting language="java"><lineannotation>// a class that uses a stateful Command-style class to perform some processing</lineannotation>
package fiona.apple;
<lineannotation>// lots of Spring-API imports</lineannotation>
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
public class CommandManager implements BeanFactoryAware {
private BeanFactory beanFactory;
public Object process(Map commandState) {
<lineannotation>// grab a new instance of the appropriate <interfacename>Command</interfacename></lineannotation>
Command command = createCommand();
<lineannotation>// set the state on the (hopefully brand new) <interfacename>Command</interfacename> instance</lineannotation>
command.setState(commandState);
return command.execute();
}
<lineannotation>// the <interfacename>Command</interfacename> returned here could be an implementation that executes asynchronously, or whatever</lineannotation>
protected Command createCommand() {
return (Command) this.beanFactory.getBean("command"); <lineannotation>// notice the Spring API dependency</lineannotation>
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
}</programlisting>
<para>The above example is generally not a desirable solution since the
business code is then aware of and coupled to the Spring Framework.
Method Injection, a somewhat advanced feature of the Spring IoC
container, allows this use case to be handled in a clean fashion.</para>
<section id="beans-factory-lookup-method-injection">
<title>Lookup method injection</title>
<sidebar>
<title>Isn't this Method Injection...</title>
<para>... somewhat like Tapestry 4.0's pages, where folks wrote
<literal>abstract</literal> properties that Tapestry would override
at runtime with implementations that did stuff? It sure is (well,
somewhat).</para>
<para>You can read more about the motivation for Method Injection in
<ulink url="http://blog.springframework.com/rod/?p=1">this blog
entry</ulink>.</para>
</sidebar>
<para>Lookup method injection refers to the ability of the container
to override methods on <emphasis>container managed beans</emphasis>,
to return the result of looking up another named bean in the
container. The lookup will typically be of a prototype bean as in the
scenario described above. The Spring Framework implements this method
injection by dynamically generating a subclass overriding the method,
using bytecode generation via the CGLIB library.</para>
<para>So if you look at the code from previous code snippet (the
<classname>CommandManager</classname> class), the Spring container is
going to dynamically override the implementation of the
<methodname>createCommand()</methodname> method. Your
<classname>CommandManager</classname> class is not going to have any
Spring dependencies, as can be seen in this reworked example
below:</para>
<programlisting language="java">package fiona.apple;
<lineannotation>// no more Spring imports! </lineannotation>
public abstract class CommandManager {
public Object process(Object commandState) {
<lineannotation>// grab a new instance of the appropriate <interfacename>Command</interfacename> interface</lineannotation>
Command command = createCommand();
<lineannotation>// set the state on the (hopefully brand new) <interfacename>Command</interfacename> instance</lineannotation>
command.setState(commandState);
return command.execute();
}
<lineannotation>// okay... but where is the implementation of this method?</lineannotation>
protected abstract Command createCommand();
}</programlisting>
<para>In the client class containing the method to be injected (the
<classname>CommandManager</classname> in this case), the method that
is to be 'injected' must have a signature of the following
form:</para>
<programlisting language="xml">&lt;public|protected&gt; [abstract] &lt;return-type&gt; theMethodName(<lineannotation>no-arguments</lineannotation>);</programlisting>
<para>If the method is <literal>abstract</literal>, the
dynamically-generated subclass will implement the method. Otherwise,
the dynamically-generated subclass will override the concrete method
defined in the original class. Let's look at an example:</para>
<programlisting language="xml"><lineannotation>&lt;!-- a stateful bean deployed as a prototype (non-singleton) --&gt;</lineannotation>
&lt;bean id="command" class="fiona.apple.AsyncCommand" scope="prototype"&gt;
<lineannotation>&lt;!-- inject dependencies here as required --&gt;</lineannotation>
&lt;/bean&gt;
<lineannotation>&lt;!-- <literal>commandProcessor</literal> uses <literal>statefulCommandHelper</literal> --&gt;</lineannotation>
&lt;bean id="commandManager" class="fiona.apple.CommandManager"&gt;
&lt;lookup-method name="createCommand" bean="command"/&gt;
&lt;/bean&gt;</programlisting>
<para>The bean identified as <emphasis>commandManager</emphasis> will
call its own method <methodname>createCommand()</methodname> whenever
it needs a new instance of the <emphasis>command</emphasis> bean. It
is important to note that the person deploying the beans must be
careful to deploy the <literal>command</literal> bean as a prototype
(if that is actually what is needed). If it is deployed as a <link
linkend="beans-factory-scopes-singleton">singleton</link>, the same
instance of the <literal>command</literal> bean will be returned each
time!</para>
<para>Please be aware that in order for this dynamic subclassing to
work, you will need to have the CGLIB jar(s) on your classpath.
Additionally, the class that the Spring container is going to subclass
cannot be <literal>final</literal>, and the method that is being
overridden cannot be <literal>final</literal> either. Also, testing a
class that has an <literal>abstract</literal> method can be somewhat
odd in that you will have to subclass the class yourself and supply a
stub implementation of the <literal>abstract</literal> method.
Finally, objects that have been the target of method injection cannot
be serialized.</para>
<tip>
<para>The interested reader may also find the
<classname>ServiceLocatorFactoryBean</classname> (in the
<literal>org.springframework.beans.factory.config</literal> package)
to be of use; the approach is similar to that of the
<classname>ObjectFactoryCreatingFactoryBean</classname>, but it
allows you to specify your own lookup interface as opposed to having
to use a Spring-specific lookup interface such as the
<interfacename>ObjectFactory</interfacename>. Consult the (copious)
Javadoc for the <classname>ServiceLocatorFactoryBean</classname> for
a full treatment of this alternative approach (that
<emphasis>does</emphasis> reduce the coupling to Spring).</para>
</tip>
</section>
<section id="beans-factory-arbitrary-method-replacement">
<title>Arbitrary method replacement</title>
<para>A less commonly useful form of method injection than Lookup
Method Injection is the ability to replace arbitrary methods in a
managed bean with another method implementation. Users may safely skip
the rest of this section (which describes this somewhat advanced
feature), until this functionality is actually needed.</para>
<para>When using XML-based configuration metadata, the
<literal>replaced-method</literal> element may be used to replace an
existing method implementation with another, for a deployed bean.
Consider the following class, with a method computeValue, which we
want to override:</para>
<programlisting language="java">public class MyValueCalculator {
public String computeValue(String input) {
<lineannotation>// some real code...</lineannotation>
}
<lineannotation>// some other methods...</lineannotation>
}</programlisting>
<para>A class implementing the
<interfacename>org.springframework.beans.factory.support.MethodReplacer</interfacename>
interface provides the new method definition.</para>
<programlisting language="java"><lineannotation>/** meant to be used to override the existing <methodname>computeValue(String)</methodname>
implementation in <classname>MyValueCalculator</classname>
*/</lineannotation>
public class ReplacementComputeValue implements MethodReplacer {
public Object reimplement(Object o, Method m, Object[] args) throws Throwable {
<lineannotation>// get the input value, work with it, and return a computed result</lineannotation>
String input = (String) args[0];
...
return ...;
}
}</programlisting>
<para>The bean definition to deploy the original class and specify the
method override would look like this:</para>
<programlisting language="xml">&lt;bean id="myValueCalculator" class="x.y.z.MyValueCalculator"&gt;
<lineannotation>&lt;!-- arbitrary method replacement --&gt;</lineannotation>
&lt;replaced-method name="computeValue" replacer="replacementComputeValue"&gt;
&lt;arg-type&gt;String&lt;/arg-type&gt;
&lt;/replaced-method&gt;
&lt;/bean&gt;
&lt;bean id="replacementComputeValue" class="a.b.c.ReplacementComputeValue"/&gt;</programlisting>
<para>One or more contained <literal>&lt;arg-type/&gt;</literal>
elements within the <literal>&lt;replaced-method/&gt;</literal>
element may be used to indicate the method signature of the method
being overridden. Note that the signature for the arguments is
actually only needed in the case that the method is actually
overloaded and there are multiple variants within the class. For
convenience, the type string for an argument may be a substring of the
fully qualified type name. For example, all the following would match
<classname>java.lang.String</classname>.</para>
<programlisting language="java"> java.lang.String
String
Str</programlisting>
<para>Since the number of arguments is often enough to distinguish
between each possible choice, this shortcut can save a lot of typing,
by allowing you to type just the shortest string that will match an
argument type.</para>
</section>
</section>
</section>
<section id="beans-factory-scopes">
<title>Bean scopes</title>
<para>When you create a bean definition what you are actually creating is
a <emphasis>recipe</emphasis> for creating actual instances of the class
defined by that bean definition. The idea that a bean definition is a
recipe is important, because it means that, just like a class, you can
potentially have many object instances created from a single
recipe.</para>
<para>You can control not only the various dependencies and configuration
values that are to be plugged into an object that is created from a
particular bean definition, but also the <firstterm>scope</firstterm> of
the objects created from a particular bean definition. This approach is
very powerful and gives you the flexibility to <emphasis>choose</emphasis>
the scope of the objects you create through configuration instead of
having to 'bake in' the scope of an object at the Java class level. Beans
can be defined to be deployed in one of a number of scopes: out of the
box, the Spring Framework supports exactly five scopes (of which three are
available only if you are using a web-aware
<interfacename>ApplicationContext</interfacename>).</para>
<para>The scopes supported out of the box are listed below:</para>
<table id="beans-factory-scopes-tbl">
<title>Bean scopes</title>
<tgroup cols="2">
<thead>
<row>
<entry align="center">Scope</entry>
<entry align="center">Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><para> <link
linkend="beans-factory-scopes-singleton">singleton</link>
</para></entry>
<entry><para>Scopes a single bean definition to a single object
instance per Spring IoC container.</para></entry>
</row>
<row>
<entry><para> <link
linkend="beans-factory-scopes-prototype">prototype</link>
</para></entry>
<entry><para>Scopes a single bean definition to any number of
object instances.</para></entry>
</row>
<row>
<entry><para> <link
linkend="beans-factory-scopes-request">request</link>
</para></entry>
<entry><para>Scopes a single bean definition to the lifecycle of a
single HTTP request; that is each and every HTTP request will have
its own instance of a bean created off the back of a single bean
definition. Only valid in the context of a web-aware Spring
<interfacename>ApplicationContext</interfacename>.</para></entry>
</row>
<row>
<entry><para> <link
linkend="beans-factory-scopes-global-session">session</link>
</para></entry>
<entry><para>Scopes a single bean definition to the lifecycle of a
HTTP <interfacename>Session</interfacename>. Only valid in the
context of a web-aware Spring
<interfacename>ApplicationContext</interfacename>.</para></entry>
</row>
<row>
<entry><para> <link
linkend="beans-factory-scopes-global-session">global
session</link> </para></entry>
<entry><para>Scopes a single bean definition to the lifecycle of a
global HTTP <interfacename>Session</interfacename>. Typically only
valid when used in a portlet context. Only valid in the context of
a web-aware Spring
<interfacename>ApplicationContext</interfacename>.</para></entry>
</row>
</tbody>
</tgroup>
</table>
<section id="beans-factory-scopes-singleton">
<title>The singleton scope</title>
<para>When a bean is a singleton, only one <emphasis>shared</emphasis>
instance of the bean will be managed, and all requests for beans with an
id or <literal>id</literal>s matching that bean definition will result
in that one specific bean instance being returned by the Spring
container.</para>
<para>To put it another way, when you define a bean definition and it is
scoped as a singleton, then the Spring IoC container will create
<emphasis>exactly one</emphasis> instance of the object defined by that
bean definition. This single instance will be stored in a cache of such
singleton beans, and <emphasis>all subsequent requests and
references</emphasis> for that named bean will result in the cached
object being returned.</para>
<para><mediaobject>
<imageobject role="fo">
<imagedata align="center" fileref="images/singleton.png"
format="PNG" />
</imageobject>
<imageobject role="html">
<imagedata align="center" fileref="images/singleton.png"
format="PNG" />
</imageobject>
</mediaobject></para>
<para>Please be aware that Spring's concept of a singleton bean is quite
different from the Singleton pattern as defined in the seminal Gang of
Four (GoF) patterns book. The GoF Singleton hard codes the scope of an
object such that one <emphasis>and only one</emphasis> instance of a
particular class will ever be created<emphasis> per
<classname>ClassLoader</classname></emphasis>. The scope of the Spring
singleton is best described as <emphasis>per container and per
bean</emphasis>. This means that if you define one bean for a particular
class in a single Spring container, then the Spring container will
create one <emphasis>and only one</emphasis> instance of the class
defined by that bean definition. <emphasis>The singleton scope is the
default scope in Spring</emphasis>. To define a bean as a singleton in
XML, you would write configuration like so:</para>
<programlisting language="xml">&lt;bean id="accountService" class="com.foo.DefaultAccountService"/&gt;
<lineannotation>&lt;!-- the following is equivalent, though redundant (singleton scope is the default); using <literal>spring-beans-2.0.dtd</literal> --&gt;</lineannotation>
&lt;bean id="accountService" class="com.foo.DefaultAccountService" scope="singleton"/&gt;
<lineannotation>&lt;!-- the following is equivalent and preserved for backward compatibility in <literal>spring-beans.dtd</literal> --&gt;</lineannotation>
&lt;bean id="accountService" class="com.foo.DefaultAccountService" singleton="true"/&gt;</programlisting>
</section>
<section id="beans-factory-scopes-prototype">
<title>The prototype scope</title>
<para>The non-singleton, prototype scope of bean deployment results in
the <emphasis>creation of a new bean instance</emphasis> every time a
request for that specific bean is made (that is, it is injected into
another bean or it is requested via a programmatic
<literal>getBean()</literal> method call on the container). As a rule of
thumb, you should use the prototype scope for all beans that are
stateful, while the singleton scope should be used for stateless
beans.</para>
<para>The following diagram illustrates the Spring prototype scope.
<emphasis>Please note that a DAO would not typically be configured as a
prototype, since a typical DAO would not hold any conversational state;
it was just easier for this author to reuse the core of the singleton
diagram.</emphasis></para>
<para><mediaobject>
<imageobject role="fo">
<imagedata align="center" fileref="images/prototype.png"
format="PNG" />
</imageobject>
<imageobject role="html">
<imagedata align="center" fileref="images/prototype.png"
format="PNG" />
</imageobject>
</mediaobject></para>
<para>To define a bean as a prototype in XML, you would write
configuration like so:</para>
<programlisting language="xml"><lineannotation>&lt;!-- using <literal>spring-beans-2.0.dtd</literal> --&gt;</lineannotation>
&lt;bean id="accountService" class="com.foo.DefaultAccountService" scope="prototype"/&gt;
<lineannotation>&lt;!-- the following is equivalent and preserved for backward compatibility in <literal>spring-beans.dtd</literal> --&gt;</lineannotation>
&lt;bean id="accountService" class="com.foo.DefaultAccountService" singleton="false"/&gt;</programlisting>
<para>There is one quite important thing to be aware of when deploying a
bean in the prototype scope, in that the lifecycle of the bean changes
slightly. Spring does not manage the complete lifecycle of a prototype
bean: the container instantiates, configures, decorates and otherwise
assembles a prototype object, hands it to the client and then has no
further knowledge of that prototype instance. This means that while
<emphasis>initialization</emphasis> lifecycle callback methods will be
called on all objects regardless of scope, in the case of prototypes,
any configured <emphasis>destruction</emphasis> lifecycle callbacks will
<emphasis>not</emphasis> be called. It is the responsibility of the
client code to clean up prototype scoped objects and release any
expensive resources that the prototype bean(s) are holding onto. (One
possible way to get the Spring container to release resources used by
prototype-scoped beans is through the use of a custom <link
linkend="beans-factory-extension-bpp">bean post-processor</link> which
would hold a reference to the beans that need to be cleaned up.)</para>
<para>In some respects, you can think of the Spring containers role when
talking about a prototype-scoped bean as somewhat of a replacement for
the Java <literal>'new'</literal> operator. All lifecycle aspects past
that point have to be handled by the client. (The lifecycle of a bean in
the Spring container is further described in the section entitled <xref
linkend="beans-factory-lifecycle" />.)</para>
</section>
<section id="beans-factory-scopes-sing-prot-interaction">
<title>Singleton beans with prototype-bean dependencies</title>
<para>When using singleton-scoped beans that have dependencies on beans
that are scoped as prototypes, please be aware that
<emphasis>dependencies are resolved at instantiation time</emphasis>.
This means that if you dependency inject a prototype-scoped bean into a
singleton-scoped bean, a brand new prototype bean will be instantiated
and then dependency injected into the singleton bean... <emphasis>but
that is all</emphasis>. That exact same prototype instance will be the
sole instance that is ever supplied to the singleton-scoped bean, which
is fine if that is what you want.</para>
<para>However, sometimes what you actually want is for the
singleton-scoped bean to be able to acquire a brand new instance of the
prototype-scoped bean again and again and again at runtime. In that case
it is no use just dependency injecting a prototype-scoped bean into your
singleton bean, because as explained above, that only happens
<emphasis>once</emphasis> when the Spring container is instantiating the
singleton bean and resolving and injecting its dependencies. If you are
in the scenario where you need to get a brand new instance of a
(prototype) bean again and again and again at runtime, you are referred
to the section entitled <xref
linkend="beans-factory-method-injection" /></para>
<note>
<title>Backwards compatibility note: specifying the lifecycle scope in
XML</title>
<para>If you are referencing the
<filename>'spring-beans.dtd'</filename> DTD in a bean definition
file(s), and you are being explicit about the lifecycle scope of your
beans you must use the "<literal>singleton</literal>" attribute to
express the lifecycle scope (remembering that the <link
linkend="beans-factory-scopes-singleton">singleton lifecycle
scope</link> is the default). If you are referencing the
<filename>'spring-beans-2.0.dtd'</filename> DTD or the Spring 2.0 XSD
schema, then you will need to use the "<literal>scope</literal>"
attribute (because the "<literal>singleton</literal>" attribute was
removed from the definition of the new DTD and XSD files in favor of
the "<literal>scope</literal>" attribute).</para>
<para>To be totally clear about this, this means that if you use the
"<literal>singleton</literal>" attribute in an XML bean definition
then you <emphasis>must</emphasis> be referencing the
<filename>'spring-beans.dtd'</filename> DTD <emphasis>in that
file</emphasis>. If you are using the "<literal>scope</literal>"
attribute then you <emphasis>must</emphasis> be referencing either the
<filename>'spring-beans-2.0.dtd'</filename> DTD or the
<filename>'spring-beans-3.0.xsd'</filename> XSD <emphasis>in that
file</emphasis>.</para>
</note>
</section>
<section id="beans-factory-scopes-other">
<title>The other scopes</title>
<para>The other scopes, namely <literal>request</literal>,
<literal>session</literal>, and <literal>global session</literal> are
for use only in web-based applications (and can be used irrespective of
which particular web application framework you are using, if indeed
any). In the interest of keeping related concepts together in one place
in the reference documentation, these scopes are described here.</para>
<note>
<para>The scopes that are described in the following paragraphs are
<emphasis>only</emphasis> available if you are using a web-aware
Spring <interfacename>ApplicationContext</interfacename>
implementation (such as
<classname>XmlWebApplicationContext</classname>). If you try using
these next scopes with regular Spring IoC containers such as the
<classname>XmlBeanFactory</classname> or
<classname>ClassPathXmlApplicationContext</classname>, you
<emphasis>will</emphasis> get an
<classname>IllegalStateException</classname> complaining about an
unknown bean scope.</para>
</note>
<section id="beans-factory-scopes-other-web-configuration">
<title>Initial web configuration</title>
<para>In order to support the scoping of beans at the
<literal>request</literal>, <literal>session</literal>, and
<literal>global session</literal> levels (web-scoped beans), some
minor initial configuration is required before you can set about
defining your bean definitions. Please note that this extra setup is
<emphasis>not</emphasis> required if you just want to use the
'standard' scopes (namely singleton and prototype).</para>
<para>Now as things stand, there are a couple of ways to effect this
initial setup depending on your particular Servlet
environment...</para>
<para>If you are accessing scoped beans within Spring Web MVC, i.e.
within a request that is processed by the Spring
<classname>DispatcherServlet</classname>, or
<classname>DispatcherPortlet</classname>, then no special setup is
necessary: <classname>DispatcherServlet</classname> and
<classname>DispatcherPortlet</classname> already expose all relevant
state.</para>
<para>When using a Servlet 2.4+ web container, with requests processed
outside of Spring's DispatcherServlet (e.g. when using JSF or Struts),
you need to add the following
<interfacename>javax.servlet.ServletRequestListener</interfacename> to
the declarations in your web application's
<literal>'web.xml'</literal> file.</para>
<programlisting language="xml">&lt;web-app&gt;
...
&lt;listener&gt;
&lt;listener-class&gt;org.springframework.web.context.request.RequestContextListener&lt;/listener-class&gt;
&lt;/listener&gt;
...
&lt;/web-app&gt;</programlisting>
<para>If you are using an older web container (Servlet 2.3), you will
need to use the provided
<interfacename>javax.servlet.Filter</interfacename> implementation.
Find below a snippet of XML configuration that has to be included in
the <literal>'web.xml'</literal> file of your web application if you
want to have access to web-scoped beans in requests outside of
Spring's DispatcherServlet on a Servlet 2.3 container. (The filter
mapping depends on the surrounding web application configuration and
so you will have to change it as appropriate.)</para>
<programlisting language="xml">&lt;web-app&gt;
..
&lt;filter&gt;
&lt;filter-name&gt;requestContextFilter&lt;/filter-name&gt;
&lt;filter-class&gt;org.springframework.web.filter.RequestContextFilter&lt;/filter-class&gt;
&lt;/filter&gt;
&lt;filter-mapping&gt;
&lt;filter-name&gt;requestContextFilter&lt;/filter-name&gt;
&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;
...
&lt;/web-app&gt;</programlisting>
<para>That's it. <classname>DispatcherServlet</classname>,
<classname>RequestContextListener</classname> and
<classname>RequestContextFilter</classname> all do exactly the same
thing, namely bind the HTTP request object to the
<classname>Thread</classname> that is servicing that request. This
makes beans that are request- and session-scoped available further
down the call chain.</para>
</section>
<section id="beans-factory-scopes-request">
<title>The request scope</title>
<para>Consider the following bean definition:</para>
<programlisting language="xml">&lt;bean id="loginAction" class="com.foo.LoginAction" scope="request"/&gt;</programlisting>
<para>With the above bean definition in place, the Spring container
will create a brand new instance of the
<classname>LoginAction</classname> bean using the
<literal>'loginAction'</literal> bean definition for each and every
HTTP request. That is, the <literal>'loginAction'</literal> bean will
be effectively scoped at the HTTP request level. You can change or
dirty the internal state of the instance that is created as much as
you want, safe in the knowledge that other requests that are also
using instances created off the back of the same
<literal>'loginAction'</literal> bean definition will not be seeing
these changes in state since they are particular to an individual
request. When the request is finished processing, the bean that is
scoped to the request will be discarded.</para>
</section>
<section id="beans-factory-scopes-session">
<title>The session scope</title>
<para>Consider the following bean definition:</para>
<programlisting language="xml">&lt;bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/&gt;</programlisting>
<para>With the above bean definition in place, the Spring container
will create a brand new instance of the
<classname>UserPreferences</classname> bean using the
<literal>'userPreferences'</literal> bean definition for the lifetime
of a single HTTP <interfacename>Session</interfacename>. In other
words, the <literal>'userPreferences'</literal> bean will be
effectively scoped at the HTTP <interfacename>Session</interfacename>
level. Just like <literal>request-scoped</literal> beans, you can
change the internal state of the instance that is created as much as
you want, safe in the knowledge that other HTTP
<interfacename>Session</interfacename> instances that are also using
instances created off the back of the same
<literal>'userPreferences'</literal> bean definition will not be
seeing these changes in state since they are particular to an
individual HTTP <interfacename>Session</interfacename>. When the HTTP
<interfacename>Session</interfacename> is eventually discarded, the
bean that is scoped to that particular HTTP
<interfacename>Session</interfacename> will also be discarded.</para>
</section>
<section id="beans-factory-scopes-global-session">
<title>The global session scope</title>
<para>Consider the following bean definition:</para>
<programlisting language="xml">&lt;bean id="userPreferences" class="com.foo.UserPreferences" scope="globalSession"/&gt;</programlisting>
<para>The <literal>global session</literal> scope is similar to the
standard HTTP <interfacename>Session</interfacename> scope (<link
linkend="beans-factory-scopes-session">described immediately
above</link>), and really only makes sense in the context of
portlet-based web applications. The portlet specification defines the
notion of a global <interfacename>Session</interfacename> that is
shared amongst all of the various portlets that make up a single
portlet web application. Beans defined at the <literal>global
session</literal> scope are scoped (or bound) to the lifetime of the
global portlet <interfacename>Session</interfacename>.</para>
<para>Please note that if you are writing a standard Servlet-based web
application and you define one or more beans as having <literal>global
session</literal> scope, the standard HTTP
<interfacename>Session</interfacename> scope will be used, and no
error will be raised.</para>
</section>
<section id="beans-factory-scopes-other-injection">
<title>Scoped beans as dependencies</title>
<para>Being able to define a bean scoped to a HTTP request or
<interfacename>Session</interfacename> (or indeed <link
linkend="beans-factory-scopes-custom">a custom scope</link> of your
own devising) is all very well, but one of the main value-adds of the
Spring IoC container is that it manages not only the instantiation of
your objects (beans), but also the wiring up of collaborators (or
dependencies). If you want to inject a (for example) HTTP request
scoped bean into another bean, you will need to inject an AOP proxy in
place of the scoped bean. That is, you need to inject a proxy object
that exposes the same public interface as the scoped object, but that
is smart enough to be able to retrieve the real, target object from
the relevant scope (for example a HTTP request) and delegate method
calls onto the real object.</para>
<note>
<para>You <emphasis>do not</emphasis> need to use the
<literal>&lt;aop:scoped-proxy/&gt;</literal> in conjunction with
beans that are scoped as <literal>singletons</literal> or
<literal>prototypes</literal>. It is an error to try to create a
scoped proxy for a singleton bean (and the resulting
<exceptionname>BeanCreationException</exceptionname> will certainly
set you straight in this regard).</para>
</note>
<para>Let's look at the configuration that is required to effect this;
the configuration is not hugely complex (it takes just one line), but
it is important to understand the <quote>why</quote> as well as the
<quote>how</quote> behind it.</para>
<programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"&gt;
<lineannotation>&lt;!-- a HTTP <interfacename>Session</interfacename>-scoped bean exposed as a proxy --&gt;</lineannotation>
&lt;bean id="userPreferences" class="com.foo.UserPreferences" <emphasis
role="bold">scope="session"</emphasis>&gt;
<lineannotation>&lt;!-- this next element effects the proxying of the surrounding bean --&gt;</lineannotation>
<emphasis role="bold">&lt;aop:scoped-proxy/&gt;</emphasis>
&lt;/bean&gt;
<lineannotation>&lt;!-- a singleton-scoped bean <emphasis role="bold">injected with a proxy to the above bean</emphasis> --&gt;</lineannotation>
&lt;bean id="userService" class="com.foo.SimpleUserService"&gt;
<lineannotation>&lt;!-- a reference to the <emphasis role="bold">proxied</emphasis> <literal>'userPreferences'</literal> bean --&gt;</lineannotation>
&lt;property name="userPreferences" ref="userPreferences"/&gt;
&lt;/bean&gt;
&lt;/beans&gt;
</programlisting>
<para>To create such a proxy, you need only to insert a child
<literal>&lt;aop:scoped-proxy/&gt;</literal> element into a scoped
bean definition (you may also need the CGLIB library on your classpath
so that the container can effect class-based proxying; you will also
need to be using <xref linkend="xsd-config" />). So, just why do you
need this <literal>&lt;aop:scoped-proxy/&gt;</literal> element in the
definition of beans scoped at the <literal>request</literal>,
<literal>session</literal>, <literal>globalSession</literal> and
'<emphasis>insert your custom scope here</emphasis>' level? The reason
is best explained by picking apart the following bean definition
(please note that the following <literal>'userPreferences'</literal>
bean definition as it stands is
<emphasis>incomplete</emphasis>):</para>
<programlisting language="xml">&lt;bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/&gt;
&lt;bean id="userManager" class="com.foo.UserManager"&gt;
&lt;property name="userPreferences" ref="userPreferences"/&gt;
&lt;/bean&gt;</programlisting>
<para>From the above configuration it is evident that the singleton
bean <literal>'userManager'</literal> is being injected with a
reference to the HTTP <interfacename>Session</interfacename>-scoped
bean <literal>'userPreferences'</literal>. The salient point here is
that the <literal>'userManager'</literal> bean is a singleton... it
will be instantiated <emphasis>exactly once</emphasis> per container,
and its dependencies (in this case only one, the
<literal>'userPreferences'</literal> bean) will also only be injected
(once!). This means that the <literal>'userManager'</literal> will
(conceptually) only ever operate on the exact same
<literal>'userPreferences'</literal> object, that is the one that it
was originally injected with. This is <emphasis>not</emphasis> what
you want when you inject a HTTP
<interfacename>Session</interfacename>-scoped bean as a dependency
into a collaborating object (typically). Rather, what we
<emphasis>do</emphasis> want is a single
<literal>'userManager'</literal> object, and then, for the lifetime of
a HTTP <interfacename>Session</interfacename>, we want to see and use
a <literal>'userPreferences'</literal> object that is specific to said
HTTP <interfacename>Session</interfacename>.</para>
<para>Rather what you need then is to inject some sort of object that
exposes the exact same public interface as the
<classname>UserPreferences</classname> class (ideally an object that
<emphasis>is a</emphasis> <classname>UserPreferences</classname>
instance) and that is smart enough to be able to go off and fetch the
<interfacename>real</interfacename>
<classname>UserPreferences</classname> object from whatever underlying
scoping mechanism we have chosen (HTTP request,
<interfacename>Session</interfacename>, etc.). We can then safely
inject this proxy object into the <literal>'userManager'</literal>
bean, which will be blissfully unaware that the
<classname>UserPreferences</classname> reference that it is holding
onto is a proxy. In the case of this example, when a
<interfacename>UserManager</interfacename> instance invokes a method
on the dependency-injected <classname>UserPreferences</classname>
object, it is really invoking a method on the proxy... the proxy will
then go off and fetch the real <classname>UserPreferences</classname>
object from (in this case) the HTTP
<interfacename>Session</interfacename>, and delegate the method
invocation onto the retrieved real
<classname>UserPreferences</classname> object.</para>
<para>That is why you need the following, correct and complete,
configuration when injecting <literal>request-</literal>,
<literal>session-</literal>, and
<literal>globalSession-scoped</literal> beans into collaborating
objects:</para>
<programlisting language="xml">&lt;bean id="userPreferences" class="com.foo.UserPreferences" scope="session"&gt;
<emphasis role="bold"><literal>&lt;aop:scoped-proxy/&gt;</literal></emphasis>
&lt;/bean&gt;
&lt;bean id="userManager" class="com.foo.UserManager"&gt;
&lt;property name="userPreferences" ref="userPreferences"/&gt;
&lt;/bean&gt;</programlisting>
<section id="beans-factory-scopes-other-injection-proxies">
<title>Choosing the type of proxy created</title>
<para>By default, when the Spring container is creating a proxy for
a bean that is marked up with the
<literal>&lt;aop:scoped-proxy/&gt;</literal> element, <emphasis>a
CGLIB-based class proxy will be created</emphasis>. This means that
you need to have the CGLIB library on the classpath of your
application.</para>
<para><emphasis>Note: CGLIB proxies will only intercept public
method calls!</emphasis> Do not call non-public methods on such a
proxy; they will not be delegated to the scoped target
object.</para>
<para>You can choose to have the Spring container create 'standard'
JDK interface-based proxies for such scoped beans by specifying
'<literal>false</literal>' for the value of the
'<literal>proxy-target-class</literal>' attribute of the
<literal>&lt;aop:scoped-proxy/&gt;</literal> element. Using JDK
interface-based proxies does mean that you don't need any additional
libraries on your application's classpath to effect such proxying,
but it does mean that the class of the scoped bean must implement at
least one interface, and <emphasis>all</emphasis> of the
collaborators into which the scoped bean is injected must be
referencing the bean via one of its interfaces.</para>
<programlisting language="xml"><lineannotation>&lt;!-- <classname>DefaultUserPreferences</classname> implements the <interfacename>UserPreferences</interfacename> interface --&gt;</lineannotation>
&lt;bean id="userPreferences" class="com.foo.DefaultUserPreferences" scope="session"&gt;
&lt;aop:scoped-proxy <emphasis role="bold">proxy-target-class="false"<literal></literal></emphasis>/&gt;
&lt;/bean&gt;
&lt;bean id="userManager" class="com.foo.UserManager"&gt;
&lt;property name="userPreferences" ref="userPreferences"/&gt;
&lt;/bean&gt;</programlisting>
<para>The section entitled <xref linkend="aop-proxying" /> may also
be of some interest with regard to understanding the nuances of
choosing whether class-based or interface-based proxying is right
for you.</para>
</section>
</section>
</section>
<section id="beans-factory-scopes-custom">
<title>Custom scopes</title>
<para>As of Spring 2.0, the bean scoping mechanism in Spring is
extensible. This means that you are not limited to just the bean scopes
that Spring provides out of the box; you can define your own scopes, or
even redefine the existing scopes (although that last one would probably
be considered bad practice - please note that you
<emphasis>cannot</emphasis> override the built-in
<literal>singleton</literal> and <literal>prototype</literal>
scopes).</para>
<section id="beans-factory-scopes-custom-creating">
<title>Creating your own custom scope</title>
<para>Scopes are defined by the
<interfacename>org.springframework.beans.factory.config.Scope</interfacename>
interface. This is the interface that you will need to implement in
order to integrate your own custom scope(s) into the Spring container,
and is described in detail below. You may wish to look at the
<interfacename>Scope</interfacename> implementations that are supplied
with the Spring Framework itself for an idea of how to go about
implementing your own. The <ulink
url="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/beans/factory/config/Scope.html">Scope
Javadoc</ulink> explains the main class to implement when you need
your own scope in more detail too.</para>
<para>The <literal>Scope</literal> interface has four methods dealing
with getting objects from the scope, removing them from the scope and
allowing them to be 'destroyed' if needed.</para>
<para>The first method should return the object from the underlying
scope. The session scope implementation for example will return the
session-scoped bean (and if it does not exist, return a new instance
of the bean, after having bound it to the session for future
reference).</para>
<programlisting language="java">Object get(String name, ObjectFactory objectFactory)</programlisting>
<para>The second method should remove the object from the underlying
scope. The session scope implementation for example, removes the
session-scoped bean from the underlying session. The object should be
returned (you are allowed to return null if the object with the
specified name wasn't found)</para>
<programlisting language="java">Object remove(String name)</programlisting>
<para>The third method is used to register callbacks the scope should
execute when it is destroyed or when the specified object in the scope
is destroyed. Please refer to the Javadoc or a Spring scope
implementation for more information on destruction callbacks.</para>
<programlisting language="java">void registerDestructionCallback(String name, Runnable destructionCallback)</programlisting>
<para>The last method deals with obtaining the conversation identifier
for the underlying scope. This identifier is different for each scope.
For a session for example, this can be the session identifier.</para>
<programlisting language="java">String getConversationId()</programlisting>
</section>
<section id="beans-factory-scopes-custom-using">
<title>Using a custom scope</title>
<para>After you have written and tested one or more custom
<interfacename>Scope</interfacename> implementations, you then need to
make the Spring container aware of your new scope(s). The central
method to register a new <interfacename>Scope</interfacename> with the
Spring container is declared on the
<interfacename>ConfigurableBeanFactory</interfacename> interface
(implemented by most of the concrete
<interfacename>BeanFactory</interfacename> implementations that ship
with Spring); this central method is displayed below:</para>
<programlisting language="java">void registerScope(String scopeName, Scope scope);</programlisting>
<para>The first argument to the
<methodname>registerScope(..)</methodname> method is the unique name
associated with a scope; examples of such names in the Spring
container itself are <literal>'singleton'</literal> and
<literal>'prototype'</literal>. The second argument to the
<methodname>registerScope(..)</methodname> method is an actual
instance of the custom <interfacename>Scope</interfacename>
implementation that you wish to register and use.</para>
<para>Let's assume that you have written your own custom
<interfacename>Scope</interfacename> implementation, and you have
registered it like so:</para>
<programlisting language="java"><lineannotation>// note: the <classname>ThreadScope</classname> class does <emphasis
role="bold">not</emphasis> ship with the Spring Framework</lineannotation>
Scope customScope = new ThreadScope();
beanFactory.registerScope("<emphasis role="bold">thread</emphasis>", customScope);</programlisting>
<para>You can then create bean definitions that adhere to the scoping
rules of your custom <interfacename>Scope</interfacename> like
so:</para>
<programlisting language="xml">&lt;bean id="..." class="..." <emphasis
role="bold">scope="thread"</emphasis>/&gt;</programlisting>
<para>If you have your own custom <interfacename>Scope</interfacename>
implementation(s), you are not just limited to only programmatic
registration of the custom scope(s). You can also do the
<interfacename>Scope</interfacename> registration declaratively, using
the <classname>CustomScopeConfigurer</classname> class.</para>
<para>The declarative registration of custom
<interfacename>Scope</interfacename> implementations using the
<classname>CustomScopeConfigurer</classname> class is shown
below:</para>
<programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"&gt;
&lt;bean class="org.springframework.beans.factory.config.CustomScopeConfigurer"&gt;
&lt;property name="scopes"&gt;
&lt;map&gt;<emphasis role="bold">
&lt;entry key="thread"&gt;
&lt;bean class="com.foo.ThreadScope"/&gt;
&lt;/entry&gt;</emphasis>
&lt;/map&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;bean id="bar" class="x.y.Bar" <emphasis role="bold">scope="thread"</emphasis>&gt;
&lt;property name="name" value="Rick"/&gt;
&lt;aop:scoped-proxy/&gt;
&lt;/bean&gt;
&lt;bean id="foo" class="x.y.Foo"&gt;
&lt;property name="bar" ref="bar"/&gt;
&lt;/bean&gt;
&lt;/beans&gt;</programlisting>
<note>
<para>Note that, when placing a &lt;aop:scoped-proxy/&gt; in a
<interfacename>FactoryBean</interfacename> implementation, it is the
factory bean itself that is scoped, not the object returned from
<methodname>getObject()</methodname>.</para>
</note>
</section>
</section>
</section>
<section id="beans-factory-nature">
<title>Customizing the nature of a bean</title>
<section id="beans-factory-lifecycle">
<title>Lifecycle callbacks</title>
<para>The Spring Framework provides several callback interfaces to
change the behavior of your bean in the container; they include
<interfacename>InitializingBean</interfacename> and
<interfacename>DisposableBean</interfacename>. Implementing these
interfaces will result in the container calling
<methodname>afterPropertiesSet()</methodname> for the former and
<methodname>destroy()</methodname> for the latter to allow the bean to
perform certain actions upon initialization and destruction.</para>
<para>Internally, the Spring Framework uses
<interfacename>BeanPostProcessor</interfacename> implementations to
process any callback interfaces it can find and call the appropriate
methods. If you need custom features or other lifecycle behavior Spring
doesn't offer out-of-the-box, you can implement a
<interfacename>BeanPostProcessor</interfacename> yourself. More
information about this can be found in the section entitled <xref
linkend="beans-factory-extension" />.</para>
<para>All the different lifecycle callback interfaces are described
below. In one of the appendices, you can find diagrams that show how
Spring manages beans, how those lifecycle features change the nature of
your beans, and how they are managed.</para>
<section id="beans-factory-lifecycle-initializingbean">
<title>Initialization callbacks</title>
<para>Implementing the
<interfacename>org.springframework.beans.factory.InitializingBean</interfacename>
interface allows a bean to perform initialization work after all
necessary properties on the bean have been set by the container. The
<interfacename>InitializingBean</interfacename> interface specifies
exactly one method:</para>
<programlisting language="java">void afterPropertiesSet() throws Exception;</programlisting>
<para>Generally, the use of the
<interfacename>InitializingBean</interfacename> interface can be
avoided and is actually discouraged since it unnecessarily couples the
code to Spring. As an alternative, bean definitions provide support
for a generic initialization method to be specified. In the case of
XML-based configuration metadata, this is done using the
<literal>'init-method'</literal> attribute. For example, the following
definition:</para>
<programlisting language="xml">&lt;bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/&gt;</programlisting>
<programlisting language="java">public class ExampleBean {
public void init() {
<lineannotation>// do some initialization work</lineannotation>
}
}</programlisting>
<para>...is exactly the same as...</para>
<programlisting language="xml">&lt;bean id="exampleInitBean" class="examples.AnotherExampleBean"/&gt;</programlisting>
<programlisting language="java">public class AnotherExampleBean implements InitializingBean {
public void afterPropertiesSet() {
<lineannotation>// do some initialization work</lineannotation>
}
}</programlisting>
<para>... but does not couple the code to Spring.</para>
</section>
<section id="beans-factory-lifecycle-disposablebean">
<title>Destruction callbacks</title>
<para>Implementing the
<interfacename>org.springframework.beans.factory.DisposableBean</interfacename>
interface allows a bean to get a callback when the container
containing it is destroyed. The
<interfacename>DisposableBean</interfacename> interface specifies a
single method:</para>
<programlisting language="java">void destroy() throws Exception;</programlisting>
<para>Generally, the use of the
<interfacename>DisposableBean</interfacename> callback interface can
be avoided and is actually discouraged since it unnecessarily couples
the code to Spring. As an alternative, bean definitions provide
support for a generic destroy method to be specified. When using
XML-based configuration metadata this is done via the
<literal>'destroy-method'</literal> attribute on the
<literal>&lt;bean/&gt;</literal>. For example, the following
definition:</para>
<programlisting language="xml">&lt;bean id="exampleInitBean" class="examples.ExampleBean" destroy-method="cleanup"/&gt;</programlisting>
<programlisting language="java">public class ExampleBean {
public void cleanup() {
<lineannotation>// do some destruction work (like releasing pooled connections)</lineannotation>
}
}</programlisting>
<para>...is exactly the same as...</para>
<programlisting language="xml">&lt;bean id="exampleInitBean" class="examples.AnotherExampleBean"/&gt;</programlisting>
<programlisting language="java">public class AnotherExampleBean implements DisposableBean {
public void destroy() {
<lineannotation>// do some destruction work (like releasing pooled connections)</lineannotation>
}
}</programlisting>
<para>... but does not couple the code to Spring.</para>
</section>
<section id="beans-factory-lifecycle-default-init-destroy-methods">
<title>Default initialization &amp; destroy methods</title>
<para>When writing initialization and destroy method callbacks that do
not use the Spring-specific
<interfacename>InitializingBean</interfacename> and
<interfacename>DisposableBean</interfacename> callback interfaces, one
typically finds oneself writing methods with names such as
<literal>init()</literal>, <literal>initialize()</literal>,
<literal>dispose()</literal>, etc. The names of such lifecycle
callback methods are (hopefully!) standardized across a project so
that all developers on a team use the same method names and thus
ensure some level of consistency.</para>
<para>The Spring container can be configured to
<literal>'look'</literal> for named initialization and destroy
callback method names on <emphasis>every</emphasis> bean. This means
that you, as an application developer, can simply write your
application classes, use a convention of having an initialization
callback called <literal>init()</literal>, and then (without having to
configure each and every bean with, in the case of XML-based
configuration, an <literal>'init-method="init"'</literal> attribute)
be safe in the knowledge that the Spring IoC container
<emphasis>will</emphasis> call that method when the bean is being
created (and in accordance with the standard lifecycle callback
contract described previously).</para>
<para>Let's look at an example to make the use of this feature
completely clear. For the sake of the example, let us say that one of
the coding conventions on a project is that all initialization
callback methods are to be named <literal>init()</literal> and that
destroy callback methods are to be called
<literal>destroy()</literal>. This leads to classes like so...</para>
<programlisting language="java">public class DefaultBlogService implements BlogService {
private BlogDao blogDao;
public void setBlogDao(BlogDao blogDao) {
this.blogDao = blogDao;
}
<lineannotation>// this is (unsurprisingly) the initialization callback method</lineannotation>
public void init() {
if (this.blogDao == null) {
throw new IllegalStateException("The [blogDao] property must be set.");
}
}
}</programlisting>
<programlisting language="xml">&lt;beans <emphasis role="bold">default-init-method="init"</emphasis>&gt;
&lt;bean id="blogService" class="com.foo.DefaultBlogService"&gt;
&lt;property name="blogDao" ref="blogDao" /&gt;
&lt;/bean&gt;
&lt;/beans&gt;</programlisting>
<para>Notice the use of the <literal>'default-init-method'</literal>
attribute on the top-level <literal>&lt;beans/&gt;</literal> element.
The presence of this attribute means that the Spring IoC container
will recognize a method called <literal>'init'</literal> on beans as
being the initialization method callback, and when a bean is being
created and assembled, if the bean's class has such a method, it will
be invoked at the appropriate time.</para>
<para>Destroy method callbacks are configured similarly (in XML that
is) using the <literal>'default-destroy-method'</literal> attribute on
the top-level <literal>&lt;beans/&gt;</literal> element.</para>
<para>The use of this feature can save you the (small) housekeeping
chore of specifying an initialization and destroy method callback on
each and every bean, and it is great for enforcing a consistent naming
convention for initialization and destroy method callbacks, as
consistency is something that should always be aimed for.</para>
<para>Consider the case where you have some existing beans where the
underlying classes already have initialization callback methods that
are named at variance with the convention. You can
<emphasis>always</emphasis> override the default by specifying (in XML
that is) the method name using the <literal>'init-method'</literal>
and <literal>'destroy-method'</literal> attributes on the
<literal>&lt;bean/&gt;</literal> element itself.</para>
<para>Finally, please be aware that the Spring container guarantees
that a configured initialization callback is called immediately after
a bean has been supplied with all of its dependencies. This means that
the initialization callback will be called on the raw bean reference,
which means that any AOP interceptors or suchlike that will ultimately
be applied to the bean will not yet be in place. A target bean is
fully created <emphasis>first</emphasis>, <emphasis>then</emphasis> an
AOP proxy (for example) with its interceptor chain is applied. Note
that, if the target bean and the proxy are defined separately, your
code can even interact with the raw target bean, bypassing the proxy.
Hence, it would be very inconsistent to apply the interceptors to the
init method, since that would couple the lifecycle of the target bean
with its proxy/interceptors and leave strange semantics when talking
to the raw target bean directly.</para>
</section>
<section id="beans-factory-lifecycle-combined-effects">
<title>Combining lifecycle mechanisms</title>
<para>As of Spring 2.5, there are three options for controlling bean
lifecycle behavior: the <link
linkend="beans-factory-lifecycle-initializingbean"><interfacename>InitializingBean</interfacename></link>
and <link
linkend="beans-factory-lifecycle-disposablebean"><interfacename>DisposableBean</interfacename></link>
callback interfaces; custom <literal>init()</literal> and
<literal>destroy()</literal> methods; and the <link
linkend="beans-postconstruct-and-predestroy-annotations"><interfacename>@PostConstruct</interfacename>
and <interfacename>@PreDestroy</interfacename>
annotations</link>.</para>
<para>When combining different lifecycle mechanisms - for example, in
a class hierarchy in which various lifecycle mechanisms are in use -
developers should be aware of the order in which these mechanisms are
applied. The following is the ordering for initialization
methods:</para>
<itemizedlist>
<listitem>
<para>Methods annotated with
<interfacename>@PostConstruct</interfacename></para>
</listitem>
<listitem>
<para><literal>afterPropertiesSet()</literal> as defined by the
<interfacename>InitializingBean</interfacename> callback
interface</para>
</listitem>
<listitem>
<para>A custom configured <literal>init()</literal> method</para>
</listitem>
</itemizedlist>
<para>Destroy methods are called in the same order:</para>
<itemizedlist>
<listitem>
<para>Methods annotated with
<interfacename>@PreDestroy</interfacename></para>
</listitem>
<listitem>
<para><literal>destroy()</literal> as defined by the
<interfacename>DisposableBean</interfacename> callback
interface</para>
</listitem>
<listitem>
<para>A custom configured <literal>destroy()</literal>
method</para>
</listitem>
</itemizedlist>
<note>
<para>If multiple lifecycle mechanisms are configured for a given
bean, and each mechanism is configured with a different method name,
then each configured method will be executed in the order listed
above; however, if the same method name is configured - for example,
<literal>init()</literal> for an initialization method - for more
than one of the aforementioned lifecycle mechanisms, that method
will only be executed once.</para>
</note>
</section>
<section id="beans-factory-shutdown">
<title>Shutting down the Spring IoC container gracefully in non-web
applications</title>
<note>
<para>This next section does not apply to web applications (in case
the title of this section did not make that abundantly clear).
Spring's web-based <interfacename>ApplicationContext</interfacename>
implementations already have code in place to handle shutting down
the Spring IoC container gracefully when the relevant web
application is being shutdown.</para>
</note>
<para>If you are using Spring's IoC container in a non-web application
environment, for example in a rich client desktop environment, and you
want the container to shutdown gracefully and call the relevant
destroy callbacks on your singleton beans, you will need to register a
shutdown hook with the JVM. This is quite easy to do (see below), and
will ensure that your Spring IoC container shuts down gracefully and
that all resources held by your singletons are released. Of course it
is still up to you to both configure the destroy callbacks for your
singletons and implement such destroy callbacks correctly.</para>
<para>So to register a shutdown hook that enables the graceful
shutdown of the relevant Spring IoC container, you simply need to call
the <methodname>registerShutdownHook()</methodname> method that is
declared on the <classname>AbstractApplicationContext</classname>
class. To wit...</para>
<programlisting language="java">import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public final class Boot {
public static void main(final String[] args) throws Exception {
AbstractApplicationContext ctx
= new ClassPathXmlApplicationContext(new String []{"beans.xml"});
<lineannotation>// add a shutdown hook for the above context... </lineannotation>
ctx.registerShutdownHook();
<lineannotation>// app runs here...</lineannotation>
<lineannotation>// main method exits, hook is called prior to the app shutting down...</lineannotation>
}
}</programlisting>
</section>
</section>
<section id="beans-factory-aware">
<title>Knowing who you are</title>
<section id="beans-factory-aware-beanfactoryaware">
<title><interfacename>BeanFactoryAware</interfacename></title>
<para>A class which implements the
<interfacename>org.springframework.beans.factory.BeanFactoryAware</interfacename>
interface is provided with a reference to the
<interfacename>BeanFactory</interfacename> that created it, when it is
created by that <interfacename>BeanFactory</interfacename>.</para>
<programlisting language="java">public interface BeanFactoryAware {
void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}</programlisting>
<para>This allows beans to manipulate the
<interfacename>BeanFactory</interfacename> that created them
programmatically, through the
<interfacename>BeanFactory</interfacename> interface, or by casting
the reference to a known subclass of this which exposes additional
functionality. Primarily this would consist of programmatic retrieval
of other beans. While there are cases when this capability is useful,
it should generally be avoided, since it couples the code to Spring
and does not follow the Inversion of Control style, where
collaborators are provided to beans as properties.</para>
<para>An alternative option that is equivalent in effect to the
<interfacename>BeanFactoryAware</interfacename>-based approach is to
use the
<classname>org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean</classname>.
(It should be noted that this approach still does not reduce the
coupling to Spring, but it does not violate the central principle of
IoC as much as the
<interfacename>BeanFactoryAware</interfacename>-based
approach.)</para>
<para>The <classname>ObjectFactoryCreatingFactoryBean</classname> is a
<link
linkend="beans-factory-extension-factorybean"><interfacename>FactoryBean</interfacename></link>
implementation that returns a reference to an object (factory) that
can in turn be used to effect a bean lookup. The
<classname>ObjectFactoryCreatingFactoryBean</classname> class does
itself implement the <interfacename>BeanFactoryAware</interfacename>
interface; what client beans are actually injected with is an instance
of the <interfacename>ObjectFactory</interfacename> interface. This is
a Spring-specific interface (and hence there is still no total
decoupling from Spring), but clients can then use the
<interfacename>ObjectFactory</interfacename>'s
<methodname>getObject()</methodname> method to effect the bean lookup
(under the hood the <interfacename>ObjectFactory</interfacename>
implementation instance that is returned simply delegates down to a
<interfacename>BeanFactory</interfacename> to actually lookup a bean
by name). All that you need to do is supply the
<classname>ObjectFactoryCreatingFactoryBean</classname> with the name
of the bean that is to be looked up. Let's look at an example:</para>
<programlisting language="java">package x.y;
public class NewsFeed {
private String news;
public void setNews(String news) {
this.news = news;
}
public String getNews() {
return this.toString() + ": '" + news + "'";
}
}</programlisting>
<programlisting language="java">package x.y;
import org.springframework.beans.factory.ObjectFactory;
public class NewsFeedManager {
private ObjectFactory factory;
public void setFactory(ObjectFactory factory) {
this.factory = factory;
}
public void printNews() {
// here is where the lookup is performed; note that there is no
// need to hard code the name of the bean that is being looked up...
NewsFeed news = (NewsFeed) factory.getObject();
System.out.println(news.getNews());
}
}</programlisting>
<para>Find below the XML configuration to wire together the above
classes using the
<classname>ObjectFactoryCreatingFactoryBean</classname>
approach.</para>
<programlisting language="xml">&lt;beans&gt;
&lt;bean id="newsFeedManager" class="x.y.NewsFeedManager"&gt;
&lt;property name="factory"&gt;
&lt;bean
class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean"&gt;
&lt;property name="targetBeanName"&gt;
&lt;idref local="newsFeed" /&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;bean id="newsFeed" class="x.y.NewsFeed" scope="prototype"&gt;
&lt;property name="news" value="... that's fit to print!" /&gt;
&lt;/bean&gt;
&lt;/beans&gt;</programlisting>
<para>And here is a small driver program to test the fact that new
(prototype) instances of the <literal>newsFeed</literal> bean are
actually being returned for each call to the injected
<interfacename>ObjectFactory</interfacename> inside the
<classname>NewsFeedManager</classname>'s
<methodname>printNews()</methodname> method.</para>
<programlisting language="java">import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import x.y.NewsFeedManager;
public class Main {
public static void main(String[] args) throws Exception {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
NewsFeedManager manager = (NewsFeedManager) ctx.getBean("newsFeedManager");
manager.printNews();
manager.printNews();
}
}</programlisting>
<para>The output from running the above program will look like so
(results will of course vary on your machine).</para>
<programlisting language="java">x.y.NewsFeed@1292d26: '... that's fit to print!'
x.y.NewsFeed@5329c5: '... that's fit to print!'</programlisting>
<para>As of Spring 2.5, you can rely upon autowiring of the
<interfacename>BeanFactory</interfacename> as yet another alternative
to implementing the <interfacename>BeanFactoryAware</interfacename>
interface. The "traditional" <literal>constructor</literal> and
<literal>byType</literal> autowiring modes (as described in the
section entitled <xref linkend="beans-factory-autowire" />) are now
capable of providing a dependency of type
<interfacename>BeanFactory</interfacename> for either a constructor
argument or setter method parameter respectively. For more flexibility
(including the ability to autowire fields and multiple parameter
methods), consider using the new annotation-based autowiring features.
In that case, the <interfacename>BeanFactory</interfacename> will be
autowired into a field, constructor argument, or method parameter that
is expecting the <interfacename>BeanFactory</interfacename> type as
long as the field, constructor, or method in question carries the
<interfacename>@Autowired</interfacename> annotation. For more
information, see the section entitled <xref
linkend="beans-autowired-annotation" />.</para>
</section>
<section id="beans-factory-aware-beannameaware">
<title><interfacename>BeanNameAware</interfacename></title>
<para>If a bean implements the
<interfacename>org.springframework.beans.factory.BeanNameAware</interfacename>
interface and is deployed in a
<interfacename>BeanFactory</interfacename>, the
<interfacename>BeanFactory</interfacename> will call the bean through
this interface to inform the bean of the <emphasis>name</emphasis> it
was deployed under. The callback will be invoked after population of
normal bean properties but before an initialization callback like
<interfacename>InitializingBean</interfacename>'s
<emphasis>afterPropertiesSet</emphasis> or a custom
init-method.</para>
</section>
</section>
</section>
<section id="beans-child-bean-definitions">
<title>Bean definition inheritance</title>
<para>A bean definition potentially contains a large amount of
configuration information, including container specific information (for
example initialization method, static factory method name, and so forth)
and constructor arguments and property values. A child bean definition is
a bean definition that inherits configuration data from a parent
definition. It is then able to override some values, or add others, as
needed. Using parent and child bean definitions can potentially save a lot
of typing. Effectively, this is a form of templating.</para>
<para>When working with a <interfacename>BeanFactory</interfacename>
programmatically, child bean definitions are represented by the
<classname>ChildBeanDefinition</classname> class. Most users will never
work with them on this level, instead configuring bean definitions
declaratively in something like the <classname>XmlBeanFactory</classname>.
When using XML-based configuration metadata a child bean definition is
indicated simply by using the <literal>'parent'</literal> attribute,
specifying the parent bean as the value of this attribute.</para>
<programlisting language="xml">&lt;bean id="inheritedTestBean" abstract="true"
class="org.springframework.beans.TestBean"&gt;
&lt;property name="name" value="parent"/&gt;
&lt;property name="age" value="1"/&gt;
&lt;/bean&gt;
&lt;bean id="inheritsWithDifferentClass"
class="org.springframework.beans.DerivedTestBean"
<emphasis role="bold">parent="inheritedTestBean"</emphasis> init-method="initialize"&gt;
&lt;property name="name" value="override"/&gt;
<lineannotation>&lt;!-- the age property value of 1 will be inherited from parent --&gt;</lineannotation>
&lt;/bean&gt;</programlisting>
<para>A child bean definition will use the bean class from the parent
definition if none is specified, but can also override it. In the latter
case, the child bean class must be compatible with the parent, that is it
must accept the parent's property values.</para>
<para>A child bean definition will inherit constructor argument values,
property values and method overrides from the parent, with the option to
add new values. If any init-method, destroy-method and/or
<literal>static</literal> factory method settings are specified, they will
override the corresponding parent settings.</para>
<para>The remaining settings will <emphasis>always</emphasis> be taken
from the child definition: <emphasis>depends on</emphasis>,
<emphasis>autowire mode</emphasis>, <emphasis>dependency check</emphasis>,
<emphasis>singleton</emphasis>, <emphasis>scope</emphasis>, <emphasis>lazy
init</emphasis>.</para>
<para>Note that in the example above, we have explicitly marked the parent
bean definition as abstract by using the <literal>abstract</literal>
attribute. In the case that the parent definition does not specify a
class, and so explicitly marking the parent bean definition as
<literal>abstract</literal> is required:</para>
<programlisting language="xml">&lt;bean id="inheritedTestBeanWithoutClass" abstract="true"&gt;
&lt;property name="name" value="parent"/&gt;
&lt;property name="age" value="1"/&gt;
&lt;/bean&gt;
&lt;bean id="inheritsWithClass" class="org.springframework.beans.DerivedTestBean"
parent="inheritedTestBeanWithoutClass" init-method="initialize"&gt;
&lt;property name="name" value="override"/&gt;
<lineannotation>&lt;!-- age will inherit the value of <literal>1</literal> from the parent bean definition--&gt;</lineannotation>
&lt;/bean&gt;</programlisting>
<para>The parent bean cannot get instantiated on its own since it is
incomplete, and it is also explicitly marked as
<literal>abstract</literal>. When a definition is defined to be
<literal>abstract</literal> like this, it is usable only as a pure
template bean definition that will serve as a parent definition for child
definitions. Trying to use such an <literal>abstract</literal> parent bean
on its own (by referring to it as a ref property of another bean, or doing
an explicit <methodname>getBean()</methodname> call with the parent bean
id), will result in an error. Similarly, the container's internal
<methodname>preInstantiateSingletons()</methodname> method will completely
ignore bean definitions which are defined as abstract.</para>
<note>
<para><literal>ApplicationContexts</literal> (but
<emphasis>not</emphasis> <literal>BeanFactories</literal>) will by
default pre-instantiate all singletons. Therefore it is important (at
least for singleton beans) that if you have a (parent) bean definition
which you intend to use only as a template, and this definition
specifies a class, you must make sure to set the
<emphasis>'abstract'</emphasis> attribute to
<emphasis>'true'</emphasis>, otherwise the application context will
actually (attempt to) pre-instantiate the <literal>abstract</literal>
bean.</para>
</note>
</section>
<section id="beans-factory-extension">
<title>Container extension points</title>
<para>The IoC component of the Spring Framework has been designed for
extension. There is typically no need for an application developer to
subclass any of the various <interfacename>BeanFactory</interfacename> or
<interfacename>ApplicationContext</interfacename> implementation classes.
The Spring IoC container can be infinitely extended by plugging in
implementations of special integration interfaces. The next few sections
are devoted to detailing all of these various integration
interfaces.</para>
<section id="beans-factory-extension-bpp">
<title>Customizing beans using
<literal>BeanPostProcessors</literal></title>
<para>The first extension point that we will look at is the
<interfacename>BeanPostProcessor</interfacename> interface. This
interface defines a number of <firstterm>callback methods</firstterm>
that you as an application developer can implement in order to provide
your own (or override the containers default) instantiation logic,
dependency-resolution logic, and so forth. If you want to do some custom
logic after the Spring container has finished instantiating, configuring
and otherwise initializing a bean, you can plug in one or more
<interfacename>BeanPostProcessor</interfacename> implementations.</para>
<para>You can configure multiple <literal>BeanPostProcessors</literal>
if you wish. You can control the order in which these
<literal>BeanPostProcessors</literal> execute by setting the
<literal>'order'</literal> property (you can only set this property if
the <interfacename>BeanPostProcessor</interfacename> implements the
<interfacename>Ordered</interfacename> interface; if you write your own
<interfacename>BeanPostProcessor</interfacename> you should consider
implementing the <interfacename>Ordered</interfacename> interface too);
consult the Javadoc for the
<interfacename>BeanPostProcessor</interfacename> and
<interfacename>Ordered</interfacename> interfaces for more
details.</para>
<note>
<para><literal>BeanPostProcessors</literal> operate on bean (or
object) <emphasis>instances</emphasis>; that is to say, the Spring IoC
container will have instantiated a bean instance for you, and
<emphasis>then</emphasis> <literal>BeanPostProcessors</literal> get a
chance to do their stuff.</para>
<para>If you want to change the actual bean definition (that is the
recipe that defines the bean), then you rather need to use a
<interfacename>BeanFactoryPostProcessor</interfacename> (described
below in the section entitled <xref
linkend="beans-factory-extension-factory-postprocessors" />.</para>
<para>Also, <literal>BeanPostProcessors</literal> are scoped
<emphasis>per-container</emphasis>. This is only relevant if you are
using container hierarchies. If you define a
<interfacename>BeanPostProcessor</interfacename> in one container, it
will <emphasis>only</emphasis> do its stuff on the beans in that
container. Beans that are defined in another container will not be
post-processed by <literal>BeanPostProcessors</literal> in another
container, even if both containers are part of the same
hierarchy.</para>
</note>
<para>The
<interfacename>org.springframework.beans.factory.config.BeanPostProcessor</interfacename>
interface consists of exactly two callback methods. When such a class is
registered as a post-processor with the container (see below for how
this registration is effected), for each bean instance that is created
by the container, the post-processor will get a callback from the
container both <emphasis>before</emphasis> any container initialization
methods (such as <emphasis>afterPropertiesSet</emphasis> and any
declared init method) are called, and also afterwards. The
post-processor is free to do what it wishes with the bean instance,
including ignoring the callback completely. A bean post-processor will
typically check for callback interfaces, or do something such as wrap a
bean with a proxy; some of the Spring AOP infrastructure classes are
implemented as bean post-processors and they do this proxy-wrapping
logic.</para>
<para>It is important to know that a
<interfacename>BeanFactory</interfacename> treats bean post-processors
slightly differently than an
<interfacename>ApplicationContext</interfacename>. An
<interfacename>ApplicationContext</interfacename> will
<emphasis>automatically detect</emphasis> any beans which are defined in
the configuration metadata which is supplied to it that implement the
<interfacename>BeanPostProcessor</interfacename> interface, and register
them as post-processors, to be then called appropriately by the
container on bean creation. Nothing else needs to be done other than
deploying the post-processors in a similar fashion to any other bean. On
the other hand, when using a <interfacename>BeanFactory</interfacename>
implementation, bean post-processors explicitly have to be registered,
with code like this:</para>
<programlisting language="java">ConfigurableBeanFactory factory = new XmlBeanFactory(...);
<lineannotation>// now register any needed <interfacename>BeanPostProcessor</interfacename> instances</lineannotation>
MyBeanPostProcessor postProcessor = new MyBeanPostProcessor();
factory.addBeanPostProcessor(postProcessor);
<lineannotation>// now start using the factory</lineannotation></programlisting>
<para>This explicit registration step is not convenient, and this is one
of the reasons why the various
<interfacename>ApplicationContext</interfacename> implementations are
preferred above plain <interfacename>BeanFactory</interfacename>
implementations in the vast majority of Spring-backed applications,
especially when using <literal>BeanPostProcessors</literal>.</para>
<note>
<title><interfacename>BeanPostProcessors</interfacename> and AOP
auto-proxying</title>
<para>Classes that implement the
<interfacename>BeanPostProcessor</interfacename> interface are
<emphasis>special</emphasis>, and so they are treated differently by
the container. All <interfacename>BeanPostProcessors</interfacename>
<emphasis>and their directly referenced beans</emphasis> will be
instantiated on startup, as part of the special startup phase of the
<interfacename>ApplicationContext</interfacename>,
<emphasis>then</emphasis> all those
<interfacename>BeanPostProcessors</interfacename> will be registered
in a sorted fashion - and applied to all further beans. Since AOP
auto-proxying is implemented as a
<interfacename>BeanPostProcessor</interfacename> itself, no
<interfacename>BeanPostProcessors</interfacename> or directly
referenced beans are eligible for auto-proxying (and thus will not
have aspects 'woven' into them.</para>
<para>For any such bean, you should see an info log message:
<emphasis><quote>Bean 'foo' is not eligible for getting processed by
all BeanPostProcessors (for example: not eligible for
auto-proxying)</quote>.</emphasis></para>
</note>
<para>Find below some examples of how to write, register, and use
<literal>BeanPostProcessors</literal> in the context of an
<interfacename>ApplicationContext</interfacename>.</para>
<section id="beans-factory-extension-bpp-examples-hw">
<title>Example: Hello World,
<interfacename>BeanPostProcessor</interfacename>-style</title>
<para>This first example is hardly compelling, but serves to
illustrate basic usage. All we are going to do is code a custom
<interfacename>BeanPostProcessor</interfacename> implementation that
simply invokes the <methodname>toString()</methodname> method of each
bean as it is created by the container and prints the resulting string
to the system console. Yes, it is not hugely useful, but serves to get
the basic concepts across before we move into the second example which
<emphasis>is</emphasis> actually useful.</para>
<para>Find below the custom
<interfacename>BeanPostProcessor</interfacename> implementation class
definition:</para>
<programlisting language="java">package scripting;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.BeansException;
public class InstantiationTracingBeanPostProcessor implements BeanPostProcessor {
<lineannotation>// simply return the instantiated bean as-is</lineannotation>
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean; <lineannotation>// we could potentially return <emphasis>any</emphasis> object reference here...</lineannotation>
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("Bean '" + beanName + "' created : " + bean.toString());
return bean;
}
}</programlisting>
<programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:lang="http://www.springframework.org/schema/lang"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/lang
http://www.springframework.org/schema/lang/spring-lang-3.0.xsd"&gt;
&lt;lang:groovy id="messenger"
script-source="classpath:org/springframework/scripting/groovy/Messenger.groovy"&gt;
&lt;lang:property name="message" value="Fiona Apple Is Just So Dreamy."/&gt;
&lt;/lang:groovy&gt;
<lineannotation>&lt;!--
when the above bean ('messenger') is instantiated, this custom
<interfacename>BeanPostProcessor</interfacename> implementation will output the fact to the system console
--&gt;</lineannotation>
&lt;bean class="scripting.InstantiationTracingBeanPostProcessor"/&gt;
&lt;/beans&gt;</programlisting>
<para>Notice how the
<classname>InstantiationTracingBeanPostProcessor</classname> is simply
defined; it doesn't even have a name, and because it is a bean it can
be dependency injected just like any other bean. (The above
configuration also just so happens to define a bean that is backed by
a Groovy script. The Spring 2.0 dynamic language support is detailed
in the chapter entitled <xref linkend="dynamic-language" />.)</para>
<para>Find below a small driver script to exercise the above code and
configuration;</para>
<programlisting language="java">import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.scripting.Messenger;
public final class Boot {
public static void main(final String[] args) throws Exception {
ApplicationContext ctx = new ClassPathXmlApplicationContext("scripting/beans.xml");
Messenger messenger = (Messenger) ctx.getBean("messenger");
System.out.println(messenger);
}
}</programlisting>
<para>The output of executing the above program will be (something
like) this:</para>
<programlisting>Bean 'messenger' created : org.springframework.scripting.groovy.GroovyMessenger@272961
org.springframework.scripting.groovy.GroovyMessenger@272961</programlisting>
</section>
<section id="beans-factory-extension-bpp-examples-rabpp">
<title>Example: The
<classname>RequiredAnnotationBeanPostProcessor</classname></title>
<para>Using callback interfaces or annotations in conjunction with a
custom <interfacename>BeanPostProcessor</interfacename> implementation
is a common means of extending the Spring IoC container. This next
example is a bit of a cop-out, in that you are directed to the section
entitled <xref linkend="metadata-annotations-required" /> which
demonstrates the usage of a custom
<interfacename>BeanPostProcessor</interfacename> implementation that
ships with the Spring distribution which ensures that JavaBean
properties on beans that are marked with an (arbitrary) annotation are
actually (configured to be) dependency-injected with a value.</para>
</section>
</section>
<section id="beans-factory-extension-factory-postprocessors">
<title>Customizing configuration metadata with
<literal>BeanFactoryPostProcessors</literal></title>
<para>The next extension point that we will look at is the
<interfacename>org.springframework.beans.factory.config.BeanFactoryPostProcessor</interfacename>.
The semantics of this interface are similar to the
<interfacename>BeanPostProcessor</interfacename>, with one major
difference: <literal>BeanFactoryPostProcessors</literal> operate on the
<emphasis>bean configuration metadata</emphasis>; that is, the Spring
IoC container will allow <literal>BeanFactoryPostProcessors</literal> to
read the configuration metadata and potentially change it
<emphasis>before</emphasis> the container has actually instantiated any
other beans.</para>
<para>You can configure multiple
<literal>BeanFactoryPostProcessors</literal> if you wish. You can
control the order in which these
<literal>BeanFactoryPostProcessors</literal> execute by setting the
<literal>'order'</literal> property (you can only set this property if
the <interfacename>BeanFactoryPostProcessor</interfacename> implements
the <interfacename>Ordered</interfacename> interface; if you write your
own <interfacename>BeanFactoryPostProcessor</interfacename> you should
consider implementing the <interfacename>Ordered</interfacename>
interface too); consult the Javadoc for the
<interfacename>BeanFactoryPostProcessor</interfacename> and
<interfacename>Ordered</interfacename> interfaces for more
details.</para>
<note>
<para>If you want to change the actual bean
<emphasis>instances</emphasis> (the objects that are created from the
configuration metadata), then you rather need to use a
<interfacename>BeanPostProcessor</interfacename> (described above in
the section entitled <xref
linkend="beans-factory-extension-bpp" />.</para>
<para>Also, <literal>BeanFactoryPostProcessors</literal> are scoped
<emphasis>per-container</emphasis>. This is only relevant if you are
using container hierarchies. If you define a
<interfacename>BeanFactoryPostProcessor</interfacename> in one
container, it will <emphasis>only</emphasis> do its stuff on the bean
definitions in that container. Bean definitions in another container
will not be post-processed by
<literal>BeanFactoryPostProcessors</literal> in another container,
even if both containers are part of the same hierarchy.</para>
</note>
<para>A bean factory post-processor is executed manually (in the case of
a <interfacename>BeanFactory</interfacename>) or automatically (in the
case of an <interfacename>ApplicationContext</interfacename>) to apply
changes of some sort to the configuration metadata that defines a
container. Spring includes a number of pre-existing bean factory
post-processors, such as
<classname>PropertyOverrideConfigurer</classname> and
<classname>PropertyPlaceholderConfigurer</classname>, both described
below. A custom <interfacename>BeanFactoryPostProcessor</interfacename>
can also be used to register custom property editors, for
example.</para>
<para>In a <interfacename>BeanFactory</interfacename>, the process of
applying a <interfacename>BeanFactoryPostProcessor</interfacename> is
manual, and will be similar to this:</para>
<programlisting language="java">XmlBeanFactory factory = new XmlBeanFactory(new FileSystemResource("beans.xml"));
<lineannotation>// bring in some property values from a <classname>Properties</classname> file</lineannotation>
PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
cfg.setLocation(new FileSystemResource("jdbc.properties"));
<lineannotation>// now actually do the replacement</lineannotation>
cfg.postProcessBeanFactory(factory);</programlisting>
<para>This explicit registration step is not convenient, and this is one
of the reasons why the various
<interfacename>ApplicationContext</interfacename> implementations are
preferred above plain <interfacename>BeanFactory</interfacename>
implementations in the vast majority of Spring-backed applications,
especially when using
<literal>BeanFactoryPostProcessors</literal>.</para>
<anchor id="beans-factory-autodetect-beanfactorypostprocessors" />
<para>An <interfacename>ApplicationContext</interfacename> will detect
any beans which are deployed into it which implement the
<interfacename>BeanFactoryPostProcessor</interfacename> interface, and
automatically use them as bean factory post-processors, at the
appropriate time. Nothing else needs to be done other than deploying
these post-processor in a similar fashion to any other bean.</para>
<note>
<para>Just as in the case of <literal>BeanPostProcessors</literal>,
you typically don't want to have
<literal>BeanFactoryPostProcessors</literal> marked as being
lazily-initialized. If they are marked as such, then the Spring
container will never instantiate them, and thus they won't get a
chance to apply their custom logic. If you are using the
<literal>'default-lazy-init'</literal> attribute on the declaration of
your <literal>&lt;beans/&gt;</literal> element, be sure to mark your
various <interfacename>BeanFactoryPostProcessor</interfacename> bean
definitions with <literal>'lazy-init="false"'</literal>.</para>
</note>
<section id="beans-factory-placeholderconfigurer">
<title>Example: the
<interfacename>PropertyPlaceholderConfigurer</interfacename></title>
<para>The <interfacename>PropertyPlaceholderConfigurer</interfacename>
is used to externalize property values from a
<interfacename>BeanFactory</interfacename> definition, into another
separate file in the standard Java <classname>Properties</classname>
format. This is useful to allow the person deploying an application to
customize environment-specific properties (for example database URLs,
usernames and passwords), without the complexity or risk of modifying
the main XML definition file or files for the container.</para>
<para>Consider the following XML-based configuration metadata
fragment, where a <interfacename>DataSource</interfacename> with
placeholder values is defined. We will configure some properties from
an external <classname>Properties</classname> file, and at runtime, we
will apply a <classname>PropertyPlaceholderConfigurer</classname> to
the metadata which will replace some properties of the
DataSource:</para>
<programlisting language="xml">&lt;bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"&gt;
&lt;property name="locations"&gt;
&lt;value&gt;classpath:com/foo/jdbc.properties&lt;/value&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource"&gt;
&lt;property name="driverClassName" value="<emphasis role="bold">${jdbc.driverClassName}</emphasis>"/&gt;
&lt;property name="url" value="<emphasis role="bold">${jdbc.url}</emphasis>"/&gt;
&lt;property name="username" value="<emphasis role="bold">${jdbc.username}</emphasis>"/&gt;
&lt;property name="password" value="<emphasis role="bold">${jdbc.password}</emphasis>"/&gt;
&lt;/bean&gt;</programlisting>
<para>The actual values come from another file in the standard Java
<classname>Properties</classname> format:</para>
<programlisting language="java">jdbc.driverClassName=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:hsql://production:9002
jdbc.username=sa
jdbc.password=root</programlisting>
<para>With the <literal>context</literal> namespace introduced in
Spring 2.5, it is possible to configure property placeholders with a
dedicated configuration element. Multiple locations may be provided as
a comma-separated list for the <literal>location</literal>
attribute.</para>
<programlisting language="xml">&lt;context:property-placeholder location="classpath:com/foo/jdbc.properties"/&gt;</programlisting>
<para>The <classname>PropertyPlaceholderConfigurer</classname> doesn't
only look for properties in the <classname>Properties</classname> file
you specify, but also checks against the Java
<classname>System</classname> properties if it cannot find a property
you are trying to use. This behavior can be customized by setting the
<literal>systemPropertiesMode</literal> property of the configurer. It
has three values, one to tell the configurer to always override, one
to let it <emphasis>never</emphasis> override and one to let it
override only if the property cannot be found in the properties file
specified. Please consult the Javadoc for the
<classname>PropertyPlaceholderConfigurer</classname> for more
information.</para>
<tip>
<title>Class name substitution</title>
<para>The <classname>PropertyPlaceholderConfigurer</classname> can
be used to substitute class names, which is sometimes useful when
you have to pick a particular implementation class at runtime. For
example:</para>
<programlisting language="xml">&lt;bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"&gt;
&lt;property name="locations"&gt;
&lt;value&gt;classpath:com/foo/strategy.properties&lt;/value&gt;
&lt;/property&gt;
&lt;property name="properties"&gt;
&lt;value&gt;custom.strategy.class=com.foo.DefaultStrategy&lt;/value&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;bean id="serviceStrategy" class="${custom.strategy.class}"/&gt;</programlisting>
<para>If the class is unable to be resolved at runtime to a valid
class, resolution of the bean will fail once it is about to be
created (which is during the
<methodname>preInstantiateSingletons()</methodname> phase of an
<interfacename>ApplicationContext</interfacename> for a
non-lazy-init bean.)</para>
</tip>
</section>
<section id="beans-factory-overrideconfigurer">
<title>Example: the
<classname>PropertyOverrideConfigurer</classname></title>
<para>The <classname>PropertyOverrideConfigurer</classname>, another
bean factory post-processor, is similar to the
<interfacename>PropertyPlaceholderConfigurer</interfacename>, but in
contrast to the latter, the original definitions can have default
values or no values at all for bean properties. If an overriding
<classname>Properties</classname> file does not have an entry for a
certain bean property, the default context definition is used.</para>
<para>Note that the bean factory definition is
<emphasis>not</emphasis> aware of being overridden, so it is not
immediately obvious when looking at the XML definition file that the
override configurer is being used. In case that there are multiple
<classname>PropertyOverrideConfigurer</classname> instances that
define different values for the same bean property, the last one will
win (due to the overriding mechanism).</para>
<para>Properties file configuration lines are expected to be in the
format:</para>
<programlisting language="java">beanName.property=value</programlisting>
<para>An example properties file might look like this:</para>
<programlisting language="java">dataSource.driverClassName=com.mysql.jdbc.Driver
dataSource.url=jdbc:mysql:mydb</programlisting>
<para>This example file would be usable against a container definition
which contains a bean called <emphasis>dataSource</emphasis>, which
has <emphasis>driver</emphasis> and <emphasis>url</emphasis>
properties.</para>
<para>Note that compound property names are also supported, as long as
every component of the path except the final property being overridden
is already non-null (presumably initialized by the constructors). In
this example...</para>
<programlisting language="java">foo.fred.bob.sammy=123</programlisting>
<para>... the <literal>sammy</literal> property of the
<literal>bob</literal> property of the <literal>fred</literal>
property of the <literal>foo</literal> bean is being set to the scalar
value <literal>123</literal>.</para>
<para><emphasis>Note:</emphasis> Specified override values are always
<emphasis>literal</emphasis> values; they are not translated into bean
references. This also applies when the original value in the XML bean
definition specifies a bean reference</para>
<para>With the <literal>context</literal> namespace introduced in
Spring 2.5, it is possible to configure property overriding with a
dedicated configuration element:</para>
<programlisting language="xml">&lt;context:property-override location="classpath:override.properties"/&gt;</programlisting>
</section>
</section>
<section id="beans-factory-extension-factorybean">
<title>Customizing instantiation logic using
<literal>FactoryBeans</literal></title>
<para>The
<interfacename>org.springframework.beans.factory.FactoryBean</interfacename>
interface is to be implemented by objects that <emphasis>are themselves
factories</emphasis>.</para>
<para>The <interfacename>FactoryBean</interfacename> interface is a
point of pluggability into the Spring IoC containers instantiation
logic. If you have some complex initialization code that is better
expressed in Java as opposed to a (potentially) verbose amount of XML,
you can create your own <interfacename>FactoryBean</interfacename>,
write the complex initialization inside that class, and then plug your
custom <interfacename>FactoryBean</interfacename> into the
container.</para>
<para>The <interfacename>FactoryBean</interfacename> interface provides
three methods:</para>
<itemizedlist>
<listitem>
<para><methodname>Object getObject()</methodname>: has to return an
instance of the object this factory creates. The instance can
possibly be shared (depending on whether this factory returns
singletons or prototypes).</para>
</listitem>
<listitem>
<para><methodname>boolean isSingleton()</methodname>: has to return
<literal>true</literal> if this
<interfacename>FactoryBean</interfacename> returns singletons,
<literal>false</literal> otherwise</para>
</listitem>
<listitem>
<para><methodname>Class getObjectType()</methodname>: has to return
either the object type returned by the
<methodname>getObject()</methodname> method or
<literal>null</literal> if the type isn't known in advance</para>
</listitem>
</itemizedlist>
<para>The <interfacename>FactoryBean</interfacename> concept and
interface is used in a number of places within the Spring Framework; at
the time of writing there are over 50 implementations of the
<interfacename>FactoryBean</interfacename> interface that ship with
Spring itself.</para>
<para>Finally, there is sometimes a need to ask a container for an
actual <interfacename>FactoryBean</interfacename> instance itself, not
the bean it produces. This may be achieved by prepending the bean id
with <literal>'&amp;'</literal> (sans quotes) when calling the
<methodname>getBean</methodname> method of the
<interfacename>BeanFactory</interfacename> (including
<interfacename>ApplicationContext</interfacename>). So for a given
<interfacename>FactoryBean</interfacename> with an id of
<literal>myBean</literal>, invoking <literal>getBean("myBean")</literal>
on the container will return the product of the
<interfacename>FactoryBean</interfacename>, but invoking
<literal>getBean("&amp;myBean")</literal> will return the
<interfacename>FactoryBean</interfacename> instance itself.</para>
</section>
</section>
<section id="context-introduction">
<title>The <interfacename>ApplicationContext</interfacename></title>
<para>While the <literal>beans</literal> package provides basic
functionality for managing and manipulating beans, including in a
programmatic way, the <literal>context</literal> package adds the <ulink
url="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/context/ApplicationContext.html"><interfacename>ApplicationContext</interfacename></ulink>
interface, which enhances <interfacename>BeanFactory</interfacename>
functionality in a more <emphasis>framework-oriented style</emphasis>.
Many users will use <interfacename>ApplicationContext</interfacename> in a
completely declarative fashion, not even having to create it manually, but
instead relying on support classes such as
<classname>ContextLoader</classname> to automatically instantiate an
<interfacename>ApplicationContext</interfacename> as part of the normal
startup process of a J2EE web-app. (Of course, it is still possible to
create an <interfacename>ApplicationContext</interfacename>
programmatically.)</para>
<para>The basis for the context package is the
<interfacename>ApplicationContext</interfacename> interface, located in
the <literal>org.springframework.context</literal> package. Deriving from
the <interfacename>BeanFactory</interfacename> interface, it provides all
the functionality of <interfacename>BeanFactory</interfacename>. To allow
working in a more framework-oriented fashion, using layering and
hierarchical contexts, the context package also provides the following
functionality:</para>
<itemizedlist>
<listitem>
<para><interfacename>MessageSource</interfacename>, providing access
to messages in i18n-style.</para>
</listitem>
<listitem>
<para><emphasis>Access to resources</emphasis>, such as URLs and
files.</para>
</listitem>
<listitem>
<para><emphasis>Event propagation</emphasis> to beans implementing the
<interfacename>ApplicationListener</interfacename> interface.</para>
</listitem>
<listitem>
<para><emphasis>Loading of multiple (hierarchical)
contexts</emphasis>, allowing each to be focused on one particular
layer, for example the web layer of an application.</para>
</listitem>
</itemizedlist>
<section id="context-introduction-ctx-vs-beanfactory">
<title><interfacename>BeanFactory</interfacename> or
<interfacename>ApplicationContext</interfacename>?</title>
<para>Short version: <emphasis>use an
<interfacename>ApplicationContext</interfacename> unless you have a
really good reason for not doing so. For those of you that are looking
for slightly more depth as to the 'but why' of the above recommendation,
keep reading.</emphasis></para>
<para>As the <interfacename>ApplicationContext</interfacename> includes
all functionality of the <interfacename>BeanFactory</interfacename>, it
is generally recommended that it be used in preference to the
<interfacename>BeanFactory</interfacename>, except for a few limited
situations such as in an <classname>Applet</classname>, where memory
consumption might be critical and a few extra kilobytes might make a
difference. However, for most 'typical' enterprise applications and
systems, the <interfacename>ApplicationContext</interfacename> is what
you will want to use. Versions of Spring 2.0 and above make
<emphasis>heavy</emphasis> use of the <link
linkend="beans-factory-extension-bpp"><interfacename>BeanPostProcessor</interfacename>
extension point</link> (to effect proxying and suchlike), and if you are
using just a plain <interfacename>BeanFactory</interfacename> then a
fair amount of support such as transactions and AOP will not take effect
(at least not without some extra steps on your part), which could be
confusing because nothing will actually be wrong with the
configuration.</para>
<para>Find below a feature matrix that lists what features are provided
by the <interfacename>BeanFactory</interfacename> and
<interfacename>ApplicationContext</interfacename> interfaces (and
attendant implementations). (The following sections describe
functionality that <interfacename>ApplicationContext</interfacename>
adds to the basic <interfacename>BeanFactory</interfacename>
capabilities in a lot more depth than the said feature matrix.)</para>
<table id="context-introduction-ctx-vs-beanfactory-feature-matrix"
pgwide="1">
<title>Feature Matrix</title>
<tgroup cols="3">
<colspec align="left" />
<thead>
<row>
<entry align="center">Feature</entry>
<entry
align="center"><interfacename>BeanFactory</interfacename></entry>
<entry
align="center"><interfacename>ApplicationContext</interfacename></entry>
</row>
</thead>
<tbody>
<row>
<entry><para>Bean instantiation/wiring</para></entry>
<entry align="center"><para>Yes</para></entry>
<entry align="center"><para>Yes</para></entry>
</row>
<row>
<entry><para>Automatic
<interfacename>BeanPostProcessor</interfacename>
registration</para></entry>
<entry align="center"><para>No</para></entry>
<entry align="center"><para>Yes</para></entry>
</row>
<row>
<entry><para>Automatic
<interfacename>BeanFactoryPostProcessor</interfacename>
registration</para></entry>
<entry align="center"><para>No</para></entry>
<entry align="center"><para>Yes</para></entry>
</row>
<row>
<entry><para>Convenient
<interfacename>MessageSource</interfacename> access (for
i18n)</para></entry>
<entry align="center"><para>No</para></entry>
<entry align="center"><para>Yes</para></entry>
</row>
<row>
<entry><para><interfacename>ApplicationEvent</interfacename>
publication</para></entry>
<entry align="center"><para>No</para></entry>
<entry align="center"><para>Yes</para></entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section id="context-functionality-messagesource">
<title>Internationalization using
<literal>MessageSources</literal></title>
<para>The <interfacename>ApplicationContext</interfacename> interface
extends an interface called
<interfacename>MessageSource</interfacename>, and therefore provides
messaging (i18n or internationalization) functionality. Together with
the <classname>HierarchicalMessageSource</classname>, capable of
resolving hierarchical messages, these are the basic interfaces Spring
provides to do message resolution. Let's quickly review the methods
defined there:</para>
<itemizedlist>
<listitem>
<para><methodname>String getMessage(String code, Object[] args,
String default, Locale loc)</methodname>: the basic method used to
retrieve a message from the
<interfacename>MessageSource</interfacename>. When no message is
found for the specified locale, the default message is used. Any
arguments passed in are used as replacement values, using the
<interfacename>MessageFormat</interfacename> functionality provided
by the standard library.</para>
</listitem>
<listitem>
<para><methodname>String getMessage(String code, Object[] args,
Locale loc)</methodname>: essentially the same as the previous
method, but with one difference: no default message can be
specified; if the message cannot be found, a
<classname>NoSuchMessageException</classname> is thrown.</para>
</listitem>
<listitem>
<para><methodname>String getMessage(MessageSourceResolvable
resolvable, Locale locale)</methodname>: all properties used in the
methods above are also wrapped in a class named
<interfacename>MessageSourceResolvable</interfacename>, which you
can use via this method.</para>
</listitem>
</itemizedlist>
<para>When an <interfacename>ApplicationContext</interfacename> gets
loaded, it automatically searches for a
<interfacename>MessageSource</interfacename> bean defined in the
context. The bean has to have the name
<literal>'messageSource'</literal>. If such a bean is found, all calls
to the methods described above will be delegated to the message source
that was found. If no message source was found, the
<interfacename>ApplicationContext</interfacename> attempts to see if it
has a parent containing a bean with the same name. If so, it uses that
bean as the <interfacename>MessageSource</interfacename>. If it can't
find any source for messages, an empty
<classname>DelegatingMessageSource</classname> will be instantiated in
order to be able to accept calls to the methods defined above.</para>
<para>Spring currently provides two
<interfacename>MessageSource</interfacename> implementations. These are
the <classname>ResourceBundleMessageSource</classname> and the
<classname>StaticMessageSource</classname>. Both implement
<interfacename>HierarchicalMessageSource</interfacename> in order to do
nested messaging. The <classname>StaticMessageSource</classname> is
hardly ever used but provides programmatic ways to add messages to the
source. The <classname>ResourceBundleMessageSource</classname> is more
interesting and is the one we will provide an example for:</para>
<programlisting language="xml">&lt;beans&gt;
&lt;bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource"&gt;
&lt;property name="basenames"&gt;
&lt;list&gt;
&lt;value&gt;format&lt;/value&gt;
&lt;value&gt;exceptions&lt;/value&gt;
&lt;value&gt;windows&lt;/value&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;/beans&gt;</programlisting>
<para>This assumes you have three resource bundles defined on your
classpath called <literal>format</literal>,
<literal>exceptions</literal> and <literal>windows</literal>. Using the
JDK standard way of resolving messages through ResourceBundles, any
request to resolve a message will be handled. For the purposes of the
example, lets assume the contents of two of the above resource bundle
files are...</para>
<programlisting language="java"><lineannotation># in 'format.properties'</lineannotation>
message=Alligators rock!</programlisting>
<programlisting language="java"><lineannotation># in 'exceptions.properties'</lineannotation>
argument.required=The '{0}' argument is required.</programlisting>
<para>Some (admittedly trivial) driver code to exercise the
<classname>MessageSource</classname> functionality can be found below.
Remember that all <classname>ApplicationContext</classname>
implementations are also <classname>MessageSource</classname>
implementations and so can be cast to the
<classname>MessageSource</classname> interface.</para>
<programlisting language="java">public static void main(String[] args) {
MessageSource resources = new ClassPathXmlApplicationContext("beans.xml");
String message = resources.getMessage("message", null, "Default", null);
System.out.println(message);
}</programlisting>
<para>The resulting output from the above program will be...</para>
<programlisting>Alligators rock!</programlisting>
<para>So to summarize, the <classname>MessageSource</classname> is
defined in a file called <literal>'beans.xml'</literal> (this file
exists at the root of your classpath). The
<literal>'messageSource'</literal> bean definition refers to a number of
resource bundles via its <literal>basenames</literal> property; the
three files that are passed in the list to the
<literal>basenames</literal> property exist as files at the root of your
classpath (and are called <literal>format.properties</literal>,
<literal>exceptions.properties</literal>, and
<literal>windows.properties</literal> respectively).</para>
<para>Lets look at another example, and this time we will look at
passing arguments to the message lookup; these arguments will be
converted into Strings and inserted into placeholders in the lookup
message. This is perhaps best explained with an example:</para>
<programlisting language="xml">&lt;beans&gt;
<lineannotation>&lt;!-- this <interfacename>MessageSource</interfacename> is being used in a web application --&gt;</lineannotation>
&lt;bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"&gt;
&lt;property name="basename" value="test-messages"/&gt;
&lt;/bean&gt;
<lineannotation>&lt;!-- let's inject the above <interfacename>MessageSource</interfacename> into this POJO --&gt;</lineannotation>
&lt;bean id="example" class="com.foo.Example"&gt;
&lt;property name="messages" ref="messageSource"/&gt;
&lt;/bean&gt;
&lt;/beans&gt;</programlisting>
<programlisting language="java">public class Example {
private MessageSource messages;
public void setMessages(MessageSource messages) {
this.messages = messages;
}
public void execute() {
String message = this.messages.getMessage("argument.required",
new Object [] {"userDao"}, "Required", null);
System.out.println(message);
}
}</programlisting>
<para>The resulting output from the invocation of the
<methodname>execute()</methodname> method will be...</para>
<programlisting>The 'userDao' argument is required.</programlisting>
<para>With regard to internationalization (i18n), Spring's various
<classname>MessageResource</classname> implementations follow the same
locale resolution and fallback rules as the standard JDK
<classname>ResourceBundle</classname>. In short, and continuing with the
example <literal>'messageSource'</literal> defined previously, if you
want to resolve messages against the British (en-GB) locale, you would
create files called <literal>format_en_GB.properties</literal>,
<literal>exceptions_en_GB.properties</literal>, and
<literal>windows_en_GB.properties</literal> respectively.</para>
<para>Locale resolution is typically going to be managed by the
surrounding environment of the application. For the purpose of this
example though, we'll just manually specify the locale that we want to
resolve our (British) messages against.</para>
<programlisting><lineannotation># in 'exceptions_en_GB.properties'</lineannotation>
argument.required=Ebagum lad, the '{0}' argument is required, I say, required.</programlisting>
<programlisting language="java">public static void main(final String[] args) {
MessageSource resources = new ClassPathXmlApplicationContext("beans.xml");
String message = resources.getMessage("argument.required",
new Object [] {"userDao"}, "Required", Locale.UK);
System.out.println(message);
}</programlisting>
<para>The resulting output from the running of the above program will
be...</para>
<programlisting>Ebagum lad, the 'userDao' argument is required, I say, required.</programlisting>
<para>The <classname>MessageSourceAware</classname> interface can also
be used to acquire a reference to any
<classname>MessageSource</classname> that has been defined. Any bean
that is defined in an <classname>ApplicationContext</classname> that
implements the <classname>MessageSourceAware</classname> interface will
be injected with the application context's
<classname>MessageSource</classname> when it (the bean) is being created
and configured.</para>
<para><emphasis>Note: As an alternative to
<classname>ResourceBundleMessageSource</classname>, Spring also provides
a <classname>ReloadableResourceBundleMessageSource</classname> class.
This variant supports the same bundle file format but is more flexible
than the standard JDK based
<classname>ResourceBundleMessageSource</classname>
implementation.</emphasis> In particular, it allows for reading files
from any Spring resource location (not just from the classpath) and
supports hot reloading of bundle property files (while efficiently
caching them in between). Check out the
<classname>ReloadableResourceBundleMessageSource</classname> javadoc for
details.</para>
</section>
<section id="context-functionality-events">
<title>Events</title>
<para>Event handling in the
<interfacename>ApplicationContext</interfacename> is provided through
the <classname>ApplicationEvent</classname> class and
<interfacename>ApplicationListener</interfacename> interface. If a bean
which implements the <interfacename>ApplicationListener</interfacename>
interface is deployed into the context, every time an
<classname>ApplicationEvent</classname> gets published to the
<interfacename>ApplicationContext</interfacename>, that bean will be
notified. Essentially, this is the standard
<emphasis>Observer</emphasis> design pattern. Spring provides the
following standard events:</para>
<table id="beans-ctx-events-tbl">
<title>Built-in Events</title>
<tgroup cols="2">
<colspec colname="c1" colwidth="2*" />
<colspec colname="c2" colwidth="5*" />
<thead>
<row>
<entry>Event</entry>
<entry>Explanation</entry>
</row>
</thead>
<tbody>
<row>
<entry><classname>ContextRefreshedEvent</classname></entry>
<entry>Published when the
<interfacename>ApplicationContext</interfacename> is initialized
or refreshed, e.g. using the <methodname>refresh()</methodname>
method on the
<interfacename>ConfigurableApplicationContext</interfacename>
interface. "Initialized" here means that all beans are loaded,
post-processor beans are detected and activated, singletons are
pre-instantiated, and the
<interfacename>ApplicationContext</interfacename> object is
ready for use. A refresh may be triggered multiple times, as
long as the context hasn't been closed - provided that the
chosen <interfacename>ApplicationContext</interfacename>
actually supports such "hot" refreshes (which e.g.
<classname>XmlWebApplicationContext</classname> does but
<classname>GenericApplicationContext</classname>
doesn't).</entry>
</row>
<row>
<entry><classname>ContextStartedEvent</classname></entry>
<entry>Published when the
<interfacename>ApplicationContext</interfacename> is started,
using the <methodname>start()</methodname> method on the
<interfacename>ConfigurableApplicationContext</interfacename>
interface. "Started" here means that all
<interfacename>Lifecycle</interfacename> beans will receive an
explicit start signal. This will typically be used for
restarting after an explicit stop, but may also be used for
starting components that haven't been configured for autostart
(e.g. haven't started on initialization already).</entry>
</row>
<row>
<entry><classname>ContextStoppedEvent</classname></entry>
<entry>Published when the
<interfacename>ApplicationContext</interfacename> is stopped,
using the <methodname>stop()</methodname> method on the
<interfacename>ConfigurableApplicationContext</interfacename>
interface. "Stopped" here means that all
<interfacename>Lifecycle</interfacename> beans will receive an
explicit stop signal. A stopped context may be restarted through
a <methodname>start()</methodname> call.</entry>
</row>
<row>
<entry><classname>ContextClosedEvent</classname></entry>
<entry>Published when the
<interfacename>ApplicationContext</interfacename> is closed,
using the <methodname>close()</methodname> method on the
<interfacename>ConfigurableApplicationContext</interfacename>
interface. "Closed" here means that all singleton beans are
destroyed. A closed context has reached its end of life; it
cannot be refreshed or restarted.</entry>
</row>
<row>
<entry><classname>RequestHandledEvent</classname></entry>
<entry>A web-specific event telling all beans that an HTTP
request has been serviced (this will be published
<emphasis>after</emphasis> the request has been finished). Note
that this event is only applicable for web applications using
Spring's <classname>DispatcherServlet</classname>.</entry>
</row>
</tbody>
</tgroup>
</table>
<para>Implementing custom events can be done as well. Simply call the
<methodname>publishEvent()</methodname> method on the
<interfacename>ApplicationContext</interfacename>, specifying a
parameter which is an instance of your custom event class implementing
<classname>ApplicationEvent</classname>. Event listeners receive events
synchronously. This means the <methodname>publishEvent()</methodname>
method blocks until all listeners have finished processing the event (it
is possible to supply an alternate event publishing strategy via a
<interfacename>ApplicationEventMulticaster</interfacename>
implementation). Furthermore, when a listener receives an event it
operates inside the transaction context of the publisher, if a
transaction context is available.</para>
<para>Let's look at an example. First, the
<interfacename>ApplicationContext</interfacename>:</para>
<programlisting language="xml">&lt;bean id="emailer" class="example.EmailBean"&gt;
&lt;property name="blackList"&gt;
&lt;list&gt;
&lt;value&gt;black@list.org&lt;/value&gt;
&lt;value&gt;white@list.org&lt;/value&gt;
&lt;value&gt;john@doe.org&lt;/value&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;bean id="blackListListener" class="example.BlackListNotifier"&gt;
&lt;property name="notificationAddress" value="spam@list.org"/&gt;
&lt;/bean&gt;</programlisting>
<para>Now, let's look at the actual classes:</para>
<programlisting language="java">public class EmailBean implements ApplicationContextAware {
private List blackList;
private ApplicationContext ctx;
public void setBlackList(List blackList) {
this.blackList = blackList;
}
public void setApplicationContext(ApplicationContext ctx) {
this.ctx = ctx;
}
public void sendEmail(String address, String text) {
if (blackList.contains(address)) {
BlackListEvent event = new BlackListEvent(address, text);
ctx.publishEvent(event);
return;
}
<lineannotation>// send email...</lineannotation>
}
}</programlisting>
<programlisting language="java">public class BlackListNotifier implements ApplicationListener {
private String notificationAddress;
public void setNotificationAddress(String notificationAddress) {
this.notificationAddress = notificationAddress;
}
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof BlackListEvent) {
<lineannotation>// notify appropriate person...</lineannotation>
}
}
}</programlisting>
<para>Of course, this particular example could probably be implemented
in better ways (perhaps by using AOP features), but it should be
sufficient to illustrate the basic event mechanism.</para>
</section>
<section id="context-functionality-resources">
<title>Convenient access to low-level resources</title>
<para>For optimal usage and understanding of application contexts, users
should generally familiarize themselves with Spring's
<interfacename>Resource</interfacename> abstraction, as described in the
chapter entitled <xref linkend="resources" />.</para>
<para>An application context is a
<interfacename>ResourceLoader</interfacename>, able to be used to load
<interfacename>Resource</interfacename>s. A
<interfacename>Resource</interfacename> is essentially a
<literal>java.net.URL</literal> on steroids (in fact, it just wraps and
uses a URL where appropriate), which can be used to obtain low-level
resources from almost any location in a transparent fashion, including
from the classpath, a filesystem location, anywhere describable with a
standard URL, and some other variations. If the resource location string
is a simple path without any special prefixes, where those resources
come from is specific and appropriate to the actual application context
type.</para>
<para>A bean deployed into the application context may implement the
special callback interface,
<interfacename>ResourceLoaderAware</interfacename>, to be automatically
called back at initialization time with the application context itself
passed in as the <interfacename>ResourceLoader</interfacename>. A bean
may also expose properties of type
<interfacename>Resource</interfacename>, to be used to access static
resources, and expect that they will be injected into it like any other
properties. The person deploying the bean may specify those
<interfacename>Resource</interfacename> properties as simple String
paths, and rely on a special JavaBean
<interfacename>PropertyEditor</interfacename> that is automatically
registered by the context, to convert those text strings to actual
<interfacename>Resource</interfacename> objects.</para>
<para>The location path or paths supplied to an
<interfacename>ApplicationContext</interfacename> constructor are
actually resource strings, and in simple form are treated appropriately
to the specific context implementation (
<classname>ClassPathXmlApplicationContext</classname> treats a simple
location path as a classpath location), but may also be used with
special prefixes to force loading of definitions from the classpath or a
URL, regardless of the actual context type.</para>
</section>
<section id="context-create">
<title>Convenient <interfacename>ApplicationContext</interfacename>
instantiation for web applications</title>
<para>As opposed to the <interfacename>BeanFactory</interfacename>,
which will often be created programmatically,
<interfacename>ApplicationContext</interfacename> instances can be
created declaratively using for example a
<classname>ContextLoader</classname>. Of course you can also create
<interfacename>ApplicationContext</interfacename> instances
programmatically using one of the
<interfacename>ApplicationContext</interfacename> implementations.
First, let's examine the <classname>ContextLoader</classname> mechanism
and its implementations.</para>
<para>The <classname>ContextLoader</classname> mechanism comes in two
flavors: the <classname>ContextLoaderListener</classname> and the
<classname>ContextLoaderServlet</classname>. They both have the same
functionality but differ in that the listener version cannot be reliably
used in Servlet 2.3 containers. Since the Servlet 2.4 specification,
servlet context listeners are required to execute immediately after the
servlet context for the web application has been created and is
available to service the first request (and also when the servlet
context is about to be shut down): as such a servlet context listener is
an ideal place to initialize the Spring
<interfacename>ApplicationContext</interfacename>. It is up to you as to
which one you use, but all things being equal you should probably prefer
<classname>ContextLoaderListener</classname>; for more information on
compatibility, have a look at the Javadoc for the
<classname>ContextLoaderServlet</classname>.</para>
<para>You can register an
<interfacename>ApplicationContext</interfacename> using the
<classname>ContextLoaderListener</classname> as follows:</para>
<programlisting language="xml">&lt;context-param&gt;
&lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
&lt;param-value&gt;/WEB-INF/daoContext.xml /WEB-INF/applicationContext.xml&lt;/param-value&gt;
&lt;/context-param&gt;
&lt;listener&gt;
&lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
&lt;/listener&gt;
<lineannotation>&lt;!-- or use the <classname>ContextLoaderServlet</classname> instead of the above listener</lineannotation><emphasis>
&lt;servlet&gt;
&lt;servlet-name&gt;context&lt;/servlet-name&gt;
&lt;servlet-class&gt;org.springframework.web.context.ContextLoaderServlet&lt;/servlet-class&gt;
&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
&lt;/servlet&gt;
--</emphasis>&gt;</programlisting>
<para>The listener inspects the
<literal>'contextConfigLocation'</literal> parameter. If the parameter
does not exist, the listener will use
<literal>/WEB-INF/applicationContext.xml</literal> as a default. When it
<emphasis>does</emphasis> exist, it will separate the String using
predefined delimiters (comma, semicolon and whitespace) and use the
values as locations where application contexts will be searched for.
Ant-style path patterns are supported as well: e.g.
<literal>/WEB-INF/*Context.xml</literal> (for all files whose name ends
with "Context.xml", residing in the "WEB-INF" directory) or
<literal>/WEB-INF/**/*Context.xml</literal> (for all such files in any
subdirectory of "WEB-INF").</para>
<para>The <classname>ContextLoaderServlet</classname> can be used
instead of the <classname>ContextLoaderListener</classname>. The servlet
will use the <literal>'contextConfigLocation'</literal> parameter just
as the listener does.</para>
</section>
</section>
<section id="beans-glue-code-and-singletons">
<title>Glue code and the evil singleton</title>
<para>The majority of the code inside an application is best written in a
DI style, where that code is served out of a Spring IoC container, has its
own dependencies supplied by the container when it is created, and is
completely unaware of the container. However, for the small glue layers of
code that are sometimes needed to tie other code together, there is
sometimes a need for singleton (or quasi-singleton) style access to a
Spring IoC container. For example, third party code may try to construct
new objects directly (<literal>Class.forName()</literal> style), without
the ability to force it to get these objects out of a Spring IoC
container. If the object constructed by the third party code is just a
small stub or proxy, which then uses a singleton style access to a Spring
IoC container to get a real object to delegate to, then inversion of
control has still been achieved for the majority of the code (the object
coming out of the container); thus most code is still unaware of the
container or how it is accessed, and remains decoupled from other code,
with all ensuing benefits. EJBs may also use this stub/proxy approach to
delegate to a plain Java implementation object, coming out of a Spring IoC
container. While the Spring IoC container itself ideally does not have to
be a singleton, it may be unrealistic in terms of memory usage or
initialization times (when using beans in the Spring IoC container such as
a Hibernate <interfacename>SessionFactory</interfacename>) for each bean
to use its own, non-singleton Spring IoC container.</para>
<para>As another example, in complex J2EE applications with multiple
layers (various JAR files, EJBs, and WAR files packaged as an EAR), with
each layer having its own Spring IoC container definition (effectively
forming a hierarchy), the preferred approach when there is only one
web-app (WAR) in the top hierarchy is to simply create one composite
Spring IoC container from the multiple XML definition files from each
layer. All of the various Spring IoC container implementations may be
constructed from multiple definition files in this fashion. However, if
there are multiple sibling web-applications at the root of the hierarchy,
it is problematic to create a Spring IoC container for each
web-application which consists of mostly identical bean definitions from
lower layers, as there may be issues due to increased memory usage, issues
with creating multiple copies of beans which take a long time to
initialize (for example a Hibernate
<interfacename>SessionFactory</interfacename>), and possible issues due to
side-effects. As an alternative, classes such as <literal><ulink
url="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/context/access/ContextSingletonBeanFactoryLocator.html">ContextSingletonBeanFactoryLocator</ulink></literal>
or <literal><ulink
url="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/beans/factory/access/SingletonBeanFactoryLocator.html">SingletonBeanFactoryLocator</ulink></literal>
may be used to demand-load multiple hierarchical (that is one container is
the parent of another) Spring IoC container instances in a singleton
fashion, which may then be used as the parents of the web-application
Spring IoC container instances. The result is that bean definitions for
lower layers are loaded only as needed, and loaded only once.</para>
<para>You can see a detailed example of the usage of these classes by
viewing the Javadoc for the <ulink
url="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/beans/factory/access/SingletonBeanFactoryLocator.html">SingletonBeanFactoryLocator</ulink>
and <ulink
url="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/context/access/ContextSingletonBeanFactoryLocator.html">ContextSingletonBeanFactoryLocator</ulink>
classes. As mentioned in the <link linkend="ejb">chapter on EJBs</link>,
the Spring convenience base classes for EJBs normally use a non-singleton
<interfacename>BeanFactoryLocator</interfacename> implementation, which is
easily replaced by the use of
<classname>SingletonBeanFactoryLocator</classname> and
<classname>ContextSingletonBeanFactoryLocator</classname>.</para>
</section>
<section id="beans-rar-deployment">
<title>Deploying a Spring ApplicationContext as a J2EE RAR file</title>
<para>Since Spring 2.5, it is possible to deploy a Spring
ApplicationContext as a RAR file, encapsulating the context and all of its
required bean classes and library JARs in a J2EE RAR deployment unit. This
is the equivalent of bootstrapping a standalone ApplicationContext, just
hosted in J2EE environment, being able to access the J2EE server's
facilities. RAR deployment is intended as a more 'natural' alternative to
the not uncommon scenario of deploying a headless WAR file - i.e. a WAR
file without any HTTP entry points, just used for bootstrapping a Spring
ApplicationContext in a J2EE environment.</para>
<para>RAR deployment is ideal for application contexts that do not need
any HTTP entry points but rather just consist of message endpoints and
scheduled jobs etc. Beans in such a context may use application server
resources such as the JTA transaction manager and JNDI-bound JDBC
DataSources and JMS ConnectionFactory instances, and may also register
with the platform's JMX server - all through Spring's standard transaction
management and JNDI and JMX support facilities. Application components may
also interact with the application's server JCA WorkManager through
Spring's <interfacename>TaskExecutor</interfacename> abstraction.</para>
<para>Check out the JavaDoc of the <ulink
url="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/jca/context/SpringContextResourceAdapter.html">SpringContextResourceAdapter</ulink>
class for the configuration details involved in RAR deployment.</para>
<para><emphasis>For simple deployment needs, all you need to do is the
following:</emphasis> Package all application classes into a RAR file
(which is just a standard JAR file with a different file extension), add
all required library jars into the root of the RAR archive, add a
"META-INF/ra.xml" deployment descriptor (as shown in
<classname>SpringContextResourceAdapter</classname>'s JavaDoc) as well as
the corresponding Spring XML bean definition file(s) (typically
"META-INF/applicationContext.xml"), and drop the resulting RAR file into
your application server's deployment directory!</para>
<para><emphasis>NOTE:</emphasis> Such RAR deployment units are usually
self-contained; they do not expose components to the 'outside' world, not
even to other modules of the same application. Interaction with a
RAR-based ApplicationContext usually happens through JMS destinations that
it shares with other modules. A RAR-based ApplicationContext may also -
for example - schedule some jobs, reacting to new files in the file system
(or the like). If it actually needs to allow for synchronous access from
the outside, it could for example export RMI endpoints, which of course
may be used by other application modules on the same machine as
well.</para>
</section>
<section id="beans-annotation-config">
<title>Annotation-based configuration</title>
<para>As mentioned in the section entitled <xref
linkend="beans-factory-extension-bpp-examples-rabpp" />, using a
<interfacename>BeanPostProcessor</interfacename> in conjunction with
annotations is a common means of extending the Spring IoC container. For
example, Spring 2.0 introduced the possibility of enforcing required
properties with the <link
linkend="metadata-annotations-required">@Required</link> annotation. As of
Spring 2.5, it is now possible to follow that same general approach to
drive Spring's dependency injection. Essentially, the
<interfacename>@Autowired</interfacename> annotation provides the same
capabilities as described in <xref linkend="beans-factory-autowire" /> but
with more fine-grained control and wider applicability. Spring 2.5 also
adds support for JSR-250 annotations such as
<interfacename>@Resource</interfacename>,
<interfacename>@PostConstruct</interfacename>, and
<interfacename>@PreDestroy</interfacename>. Use of these annotations also
requires that certain <interfacename>BeanPostProcessors</interfacename> be
registered within the Spring container. As always, these can be registered
as individual bean definitions, but they can also be implicitly registered
by including the following tag in an XML-based Spring configuration
(notice the inclusion of the '<literal>context</literal>'
namespace):</para>
<programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<lineannotation>xmlns:context="http://www.springframework.org/schema/context"</lineannotation>
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"&gt;
<lineannotation>&lt;context:annotation-config/&gt;</lineannotation>
&lt;/beans&gt;</programlisting>
<para>(The implicitly registered post-processors include <ulink
url="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html"><classname>AutowiredAnnotationBeanPostProcessor</classname></ulink>,
<ulink
url="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.html"><classname>CommonAnnotationBeanPostProcessor</classname></ulink>,
<ulink
url="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html"><classname>PersistenceAnnotationBeanPostProcessor</classname></ulink>,
as well as the aforementioned <ulink
url="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessor.html"><classname>RequiredAnnotationBeanPostProcessor</classname></ulink>.)</para>
<note>
<para>Note that <literal>&lt;context:annotation-config/&gt;</literal>
only looks for annotations on beans in the same application context it
is defined in. This means that, if you put
<literal>&lt;context:annotation-config/&gt;</literal> in a
<interfacename>WebApplicationContext</interfacename> for a
<classname>DispatcherServlet</classname>, it only checks for
<interfacename>@Autowired</interfacename> beans in your controllers, and
not your services. See <xref linkend="mvc-servlet" /> for more
information.</para>
</note>
<section id="beans-required-annotation">
<title><interfacename>@Required</interfacename></title>
<para>The <interfacename>@Required</interfacename> annotation applies to
bean property setter methods, as in the following example:</para>
<programlisting language="java">public class SimpleMovieLister {
private MovieFinder movieFinder;
@Required
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
<lineannotation>// ...</lineannotation>
}</programlisting>
<para>This annotation simply indicates that the affected bean property
must be populated at configuration time: either through an explicit
property value in a bean definition or through autowiring. The container
will throw an exception if the affected bean property has not been
populated; this allows for eager and explicit failure, avoiding
<classname>NullPointerException</classname>s or the like later on. Note
that it is still recommended to put assertions into the bean class
itself (for example into an init method) in order to enforce those
required references and values even when using the class outside of a
container.</para>
</section>
<section id="beans-autowired-annotation">
<title><interfacename>@Autowired</interfacename></title>
<para>As expected, the <interfacename>@Autowired</interfacename>
annotation may be applied to "traditional" setter methods:</para>
<programlisting language="java">public class SimpleMovieLister {
private MovieFinder movieFinder;
@Autowired
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
<lineannotation>// ...</lineannotation>
}</programlisting>
<para>The annotation may also be applied to methods with arbitrary names
and/or multiple arguments:</para>
<programlisting language="java">public class MovieRecommender {
private MovieCatalog movieCatalog;
private CustomerPreferenceDao customerPreferenceDao;
@Autowired
public void prepare(MovieCatalog movieCatalog, CustomerPreferenceDao customerPreferenceDao) {
this.movieCatalog = movieCatalog;
this.customerPreferenceDao = customerPreferenceDao;
}
<lineannotation>// ...</lineannotation>
}</programlisting>
<para>The <interfacename>@Autowired</interfacename> annotation may even
be applied on constructors and fields:</para>
<programlisting language="java">public class MovieRecommender {
@Autowired
private MovieCatalog movieCatalog;
private CustomerPreferenceDao customerPreferenceDao;
@Autowired
public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
this.customerPreferenceDao = customerPreferenceDao;
}
<lineannotation>// ...</lineannotation>
}</programlisting>
<para>It is also possible to provide <emphasis>all</emphasis> beans of a
particular type from the
<interfacename>ApplicationContext</interfacename> by adding the
annotation to a field or method that expects an array of that
type:</para>
<programlisting language="java">public class MovieRecommender {
@Autowired
private MovieCatalog[] movieCatalogs;
<lineannotation>// ...</lineannotation>
}</programlisting>
<para>The same applies for typed collections:</para>
<programlisting language="java">public class MovieRecommender {
private Set&lt;MovieCatalog&gt; movieCatalogs;
@Autowired
public void setMovieCatalogs(Set&lt;MovieCatalog&gt; movieCatalogs) {
this.movieCatalogs = movieCatalogs;
}
<lineannotation>// ...</lineannotation>
}</programlisting>
<para>Even typed Maps may be autowired as long as the expected key type
is <classname>String</classname>. The Map values will contain all beans
of the expected type, and the keys will contain the corresponding bean
names:</para>
<programlisting language="java">public class MovieRecommender {
private Map&lt;String, MovieCatalog&gt; movieCatalogs;
@Autowired
public void setMovieCatalogs(Map&lt;String, MovieCatalog&gt; movieCatalogs) {
this.movieCatalogs = movieCatalogs;
}
<lineannotation>// ...</lineannotation>
}</programlisting>
<para>By default, the autowiring will fail whenever
<emphasis>zero</emphasis> candidate beans are available; the default
behavior is to treat annotated methods, constructors, and fields as
indicating <emphasis>required</emphasis> dependencies. This behavior can
be changed as demonstrated below.</para>
<programlisting language="java">public class SimpleMovieLister {
private MovieFinder movieFinder;
@Autowired(required=false)
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
<lineannotation>// ...</lineannotation>
}</programlisting>
<note>
<para>Only <emphasis>one annotated constructor per-class</emphasis>
may be marked as <emphasis>required</emphasis>, but multiple
non-required constructors can be annotated. In that case, each will be
considered among the candidates and Spring will use the
<emphasis>greediest</emphasis> constructor whose dependencies can be
satisfied.</para>
<para>Prefer the use of <interfacename>@Autowired</interfacename>'s
<emphasis>required</emphasis> attribute over the
<interfacename>@Required</interfacename> annotation. The
<emphasis>required</emphasis> attribute indicates that the property is
not required for autowiring purposes, simply skipping it if it cannot
be autowired. <interfacename>@Required</interfacename>, on the other
hand, is stronger in that it enforces the property to have been set in
any of the container's supported ways; if no value has been injected,
a corresponding exception will be raised.</para>
</note>
<para><interfacename>@Autowired</interfacename> may also be used for
well-known "resolvable dependencies": the
<interfacename>BeanFactory</interfacename> interface, the
<interfacename>ApplicationContext</interfacename> interface, the
<interfacename>ResourceLoader</interfacename> interface, the
<interfacename>ApplicationEventPublisher</interfacename> interface and
the <interfacename>MessageSource</interfacename> interface. These
interfaces (and their extended interfaces such as
<interfacename>ConfigurableApplicationContext</interfacename> or
<interfacename>ResourcePatternResolver</interfacename>) will be
automatically resolved, with no special setup necessary.</para>
<programlisting language="java">public class MovieRecommender {
@Autowired
private ApplicationContext context;
public MovieRecommender() {
}
<lineannotation>// ...</lineannotation>
}</programlisting>
</section>
<section id="beans-autowired-annotation-qualifiers">
<title>Fine-tuning annotation-based autowiring with qualifiers</title>
<para>Since autowiring by type may lead to multiple candidates, it is
often necessary to have more control over the selection process. One way
to accomplish this is with Spring's
<interfacename>@Qualifier</interfacename> annotation. This allows for
associating qualifier values with specific arguments, narrowing the set
of type matches so that a specific bean is chosen for each argument. In
the simplest case, this can be a plain descriptive value:</para>
<programlisting language="java">public class MovieRecommender {
@Autowired
<emphasis role="bold">@Qualifier("main")</emphasis>
private MovieCatalog movieCatalog;
<lineannotation>// ...</lineannotation>
}</programlisting>
<para>The <interfacename>@Qualifier</interfacename> annotation can also
be specified on individual constructor arguments or method
parameters:</para>
<programlisting language="java">public class MovieRecommender {
private MovieCatalog movieCatalog;
private CustomerPreferenceDao customerPreferenceDao;
@Autowired
public void prepare(<emphasis role="bold">@Qualifier("main")</emphasis> MovieCatalog movieCatalog, CustomerPreferenceDao customerPreferenceDao) {
this.movieCatalog = movieCatalog;
this.customerPreferenceDao = customerPreferenceDao;
}
<lineannotation>// ...</lineannotation>
}</programlisting>
<para>The corresponding bean definitions would look like as follows. The
bean with qualifier value "main" would be wired with the constructor
argument that has been qualified with the same value.</para>
<programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"&gt;
&lt;context:annotation-config/&gt;
&lt;bean class="example.SimpleMovieCatalog"&gt;
<emphasis role="bold">&lt;qualifier value="main"/&gt;</emphasis>
<lineannotation>&lt;!-- inject any dependencies required by this bean --&gt;</lineannotation>
&lt;/bean&gt;
&lt;bean class="example.SimpleMovieCatalog"&gt;
<emphasis role="bold">&lt;qualifier value="action"/&gt;</emphasis>
<lineannotation>&lt;!-- inject any dependencies required by this bean --&gt;</lineannotation>
&lt;/bean&gt;
&lt;bean id="movieRecommender" class="example.MovieRecommender"/&gt;
&lt;/beans&gt;
</programlisting>
<para>For a fallback match, the bean name is considered as a default
qualifier value. This means that the bean may be defined with an id
"main" instead of the nested qualifier element, leading to the same
matching result. However, note that while this can be used to refer to
specific beans by name, <interfacename>@Autowired</interfacename> is
fundamentally about type-driven injection with optional semantic
qualifiers. This means that qualifier values, even when using the bean
name fallback, always have narrowing semantics within the set of type
matches; they do not semantically express a reference to a unique bean
id. Good qualifier values would be "main" or "EMEA" or "persistent",
expressing characteristics of a specific component - independent from
the bean id (which may be auto-generated in case of an anonymous bean
definition like the one above).</para>
<para>Qualifiers also apply to typed collections (as discussed above):
e.g. to <literal>Set&lt;MovieCatalog&gt;</literal>. In such a case, all
matching beans according to the declared qualifiers are going to be
injected as a collection. This implies that qualifiers do not have to be
unique; they rather simply constitute filtering criteria. For example,
there could be multiple <classname>MovieCatalog</classname> beans
defined with the same qualifier value "action"; all of which would be
injected into a <literal>Set&lt;MovieCatalog&gt;</literal> annotated
with <literal>@Qualifier("action")</literal>.</para>
<tip>
<para>If you intend to express annotation-driven injection by name, do
not primarily use <interfacename>@Autowired</interfacename> - even if
is technically capable of referring to a bean name through
<interfacename>@Qualifier</interfacename> values. Instead, prefer the
JSR-250 <interfacename>@Resource</interfacename> annotation which is
semantically defined to identify a specific target component by its
unique name, with the declared type being irrelevant for the matching
process.</para>
<para>As a specific consequence of this semantic difference, beans
which are themselves defined as a collection or map type cannot be
injected via <interfacename>@Autowired</interfacename> since type
matching is not properly applicable to them. Use
<interfacename>@Resource</interfacename> for such beans, referring to
the specific collection/map bean by unique name.</para>
<para><emphasis>Note:</emphasis> In contrast to
<interfacename>@Autowired</interfacename> which is applicable to
fields, constructors and multi-argument methods (allowing for
narrowing through qualifier annotations at the parameter level),
<interfacename>@Resource</interfacename> is only supported for fields
and bean property setter methods with a single argument. As a
consequence, stick with qualifiers if your injection target is a
constructor or a multi-argument method.</para>
</tip>
<para>You may create your own custom qualifier annotations as well.
Simply define an annotation and provide the
<interfacename>@Qualifier</interfacename> annotation within your
definition:</para>
<programlisting language="java">@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
<emphasis role="bold">@Qualifier</emphasis>
public @interface Genre {
String value();
}</programlisting>
<para>Then you can provide the custom qualifier on autowired fields and
parameters:</para>
<programlisting language="java">public class MovieRecommender {
@Autowired
<emphasis role="bold">@Genre("Action")</emphasis>
private MovieCatalog actionCatalog;
private MovieCatalog comedyCatalog;
@Autowired
public void setComedyCatalog(<emphasis role="bold">@Genre("Comedy")</emphasis> MovieCatalog comedyCatalog) {
this.comedyCatalog = comedyCatalog;
}
<lineannotation>// ...</lineannotation>
}</programlisting>
<para>The next step is to provide the information on the candidate bean
definitions. You can add <literal>&lt;qualifier/&gt;</literal> tags as
sub-elements of the <literal>&lt;bean/&gt;</literal> tag and then
specify the <literal>'type'</literal> and <literal>'value'</literal> to
match your custom qualifier annotations. The type will be matched
against the fully-qualified class name of the annotation, or as a
convenience when there is no risk of conflicting names, you may use the
'short' class name. Both are demonstrated in the following
example.</para>
<programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"&gt;
&lt;context:annotation-config/&gt;
&lt;bean class="example.SimpleMovieCatalog"&gt;
<emphasis role="bold">&lt;qualifier type="Genre" value="Action"/&gt;</emphasis>
<lineannotation>&lt;!-- inject any dependencies required by this bean --&gt;</lineannotation>
&lt;/bean&gt;
&lt;bean class="example.SimpleMovieCatalog"&gt;
<emphasis role="bold">&lt;qualifier type="example.Genre" value="Comedy"/&gt;</emphasis>
<lineannotation>&lt;!-- inject any dependencies required by this bean --&gt;</lineannotation>
&lt;/bean&gt;
&lt;bean id="movieRecommender" class="example.MovieRecommender"/&gt;
&lt;/beans&gt;
</programlisting>
<para>In the next section, entitled <xref
linkend="beans-classpath-scanning" />, you will see an annotation-based
alternative to providing the qualifier metadata in XML. Specifically,
see: <xref linkend="beans-scanning-qualifiers" />.</para>
<para>In some cases, it may be sufficient to use an annotation without a
value. This may be useful when the annotation serves a more generic
purpose and could be applied across several different types of
dependencies. For example, you may provide an
<emphasis>offline</emphasis> catalog that would be searched when no
Internet connection is available. First define the simple
annotation:</para>
<programlisting language="java">@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Offline {
}</programlisting>
<para>Then add the annotation to the field or property to be
autowired:</para>
<programlisting language="java">public class MovieRecommender {
@Autowired
<emphasis role="bold">@Offline</emphasis>
private MovieCatalog offlineCatalog;
<lineannotation>// ...</lineannotation>
}</programlisting>
<para>Now the bean definition only needs a qualifier
<literal>'type'</literal>:</para>
<programlisting language="xml">&lt;bean class="example.SimpleMovieCatalog"&gt;
<emphasis role="bold">&lt;qualifier type="Offline"/&gt;</emphasis>
<lineannotation>&lt;!-- inject any dependencies required by this bean --&gt;</lineannotation>
&lt;/bean&gt;</programlisting>
<para>It is also possible to define custom qualifier annotations that
accept named attributes in addition to or instead of the simple
<literal>'value'</literal> attribute. If multiple attribute values are
then specified on a field or parameter to be autowired, a bean
definition must match <emphasis>all</emphasis> such attribute values to
be considered an autowire candidate. As an example, consider the
following annotation definition:</para>
<programlisting language="java">@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface MovieQualifier {
String genre();
Format format();
}</programlisting>
<para>In this case <literal>Format</literal> is an enum:</para>
<programlisting language="java">public enum Format {
VHS, DVD, BLURAY
}</programlisting>
<para>The fields to be autowired are annotated with the custom qualifier
and include values for both attributes: <literal>'genre'</literal> and
<literal>'format'</literal>.</para>
<programlisting language="java">public class MovieRecommender {
@Autowired
@MovieQualifier(format=Format.VHS, genre="Action")
private MovieCatalog actionVhsCatalog;
@Autowired
@MovieQualifier(format=Format.VHS, genre="Comedy")
private MovieCatalog comedyVhsCatalog;
@Autowired
@MovieQualifier(format=Format.DVD, genre="Action")
private MovieCatalog actionDvdCatalog;
@Autowired
@MovieQualifier(format=Format.BLURAY, genre="Comedy")
private MovieCatalog comedyBluRayCatalog;
<lineannotation>// ...</lineannotation>
}</programlisting>
<para>Finally, the bean definitions should contain matching qualifier
values. This example also demonstrates that bean
<emphasis>meta</emphasis> attributes may be used instead of the
<literal>&lt;qualifier/&gt;</literal> sub-elements. If available, the
<literal>&lt;qualifier/&gt;</literal> and its attributes would take
precedence, but the autowiring mechanism will fallback on the values
provided within the <literal>&lt;meta/&gt;</literal> tags if no such
qualifier is present (see the last 2 bean definitions below).</para>
<programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"&gt;
&lt;context:annotation-config/&gt;
&lt;bean class="example.SimpleMovieCatalog"&gt;
&lt;qualifier type="MovieQualifier"&gt;
&lt;attribute key="format" value="VHS"/&gt;
&lt;attribute key="genre" value="Action"/&gt;
&lt;/qualifier&gt;
<lineannotation>&lt;!-- inject any dependencies required by this bean --&gt;</lineannotation>
&lt;/bean&gt;
&lt;bean class="example.SimpleMovieCatalog"&gt;
&lt;qualifier type="MovieQualifier"&gt;
&lt;attribute key="format" value="VHS"/&gt;
&lt;attribute key="genre" value="Comedy"/&gt;
&lt;/qualifier&gt;
<lineannotation>&lt;!-- inject any dependencies required by this bean --&gt;</lineannotation>
&lt;/bean&gt;
&lt;bean class="example.SimpleMovieCatalog"&gt;
&lt;meta key="format" value="DVD"/&gt;
&lt;meta key="genre" value="Action"/&gt;
<lineannotation>&lt;!-- inject any dependencies required by this bean --&gt;</lineannotation>
&lt;/bean&gt;
&lt;bean class="example.SimpleMovieCatalog"&gt;
&lt;meta key="format" value="BLURAY"/&gt;
&lt;meta key="genre" value="Comedy"/&gt;
<lineannotation>&lt;!-- inject any dependencies required by this bean --&gt;</lineannotation>
&lt;/bean&gt;
&lt;/beans&gt;</programlisting>
</section>
<section id="beans-custom-autowire-configurer">
<title><classname>CustomAutowireConfigurer</classname></title>
<para>The <ulink
url="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/beans/factory/annotation/CustomAutowireConfigurer.html"><classname>CustomAutowireConfigurer</classname></ulink>
is a <interfacename>BeanFactoryPostProcessor</interfacename> that
enables further customization of the autowiring process. Specifically,
it allows you to register your own custom qualifier annotation types
even if they are not themselves annotated with Spring's
<interfacename>@Qualifier</interfacename> annotation.</para>
<programlisting language="xml">&lt;bean id="customAutowireConfigurer" class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer"&gt;
&lt;property name="customQualifierTypes"&gt;
&lt;set&gt;
&lt;value&gt;example.CustomQualifier&lt;/value&gt;
&lt;/set&gt;
&lt;/property&gt;
&lt;/bean&gt;</programlisting>
<para>Note that the particular implementation of
<interfacename>AutowireCandidateResolver</interfacename> that will be
activated for the application context depends upon the Java version. If
running on less than Java 5, the qualifier annotations are not
supported, and therefore autowire candidates are solely determined by
the <literal>'autowire-candidate'</literal> value of each bean
definition as well as any
<literal>'default-autowire-candidates'</literal> pattern(s) available on
the <literal>&lt;beans/&gt;</literal> element. If running on Java 5 or
greater, the presence of <interfacename>@Qualifier</interfacename>
annotations or any custom annotations registered with the
<classname>CustomAutowireConfigurer</classname> will also play a
role.</para>
<para>Regardless of the Java version, the determination of a "primary"
candidate (when multiple beans qualify as autowire candidates) is the
same: if exactly one bean definition among the candidates has a
<literal>'primary'</literal> attribute set to <literal>'true'</literal>,
it will be selected.</para>
</section>
<section id="beans-resource-annotation">
<title><interfacename>@Resource</interfacename></title>
<para>Spring also supports injection using the JSR-250
<interfacename>@Resource</interfacename> annotation on fields or bean
property setter methods. This is a common pattern found in Java EE 5 and
Java 6 (e.g. in JSF 1.2 managed beans or JAX-WS 2.0 endpoints), which
Spring supports for Spring-managed objects as well.</para>
<para><interfacename>@Resource</interfacename> takes a 'name' attribute,
and by default Spring will interpret that value as the bean name to be
injected. In other words, it follows <emphasis>by-name</emphasis>
semantics as demonstrated in this example:</para>
<programlisting language="java">public class SimpleMovieLister {
private MovieFinder movieFinder;
<emphasis role="bold">@Resource(name="myMovieFinder")</emphasis>
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
}</programlisting>
<para>If no name is specified explicitly, then the default name will be
derived from the name of the field or setter method: In case of a field,
it will simply be equivalent to the field name; in case of a setter
method, it will be equivalent to the bean property name. So the
following example is going to have the bean with name "movieFinder"
injected into its setter method:</para>
<programlisting language="java">public class SimpleMovieLister {
private MovieFinder movieFinder;
<emphasis role="bold">@Resource</emphasis>
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
}</programlisting>
<note>
<para>The name provided with the annotation will be resolved as a bean
name by the <interfacename>BeanFactory</interfacename> of which the
<classname>CommonAnnotationBeanPostProcessor</classname> is aware.
Note that the names may be resolved via JNDI if Spring's <ulink
url="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/jndi/support/SimpleJndiBeanFactory.html"><classname>SimpleJndiBeanFactory</classname></ulink>
is configured explicitly. However, it is recommended to rely on the
default behavior and simply use Spring's JNDI lookup capabilities to
preserve the level of indirection.</para>
</note>
<para>Similar to <interfacename>@Autowired</interfacename>,
<interfacename>@Resource</interfacename> may fall back to standard bean
type matches (i.e. find a primary type match instead of a specific named
bean) as well as resolve well-known "resolvable dependencies": the
<interfacename>BeanFactory</interfacename> interface, the
<interfacename>ApplicationContext</interfacename> interface, the
<interfacename>ResourceLoader</interfacename> interface, the
<interfacename>ApplicationEventPublisher</interfacename> interface and
the <interfacename>MessageSource</interfacename> interface. Note that
this only applies to <interfacename>@Resource</interfacename> usage with
no explicit name specified!</para>
<para>So the following example will have its
<literal>customerPreferenceDao</literal> field looking for a bean with
name "customerPreferenceDao" first, then falling back to a primary type
match for the type <classname>CustomerPreferenceDao</classname>. The
"context" field will simply be injected based on the known resolvable
dependency type
<interfacename>ApplicationContext</interfacename>.</para>
<programlisting language="java">public class MovieRecommender {
@Resource
private CustomerPreferenceDao customerPreferenceDao;
@Resource
private ApplicationContext context;
public MovieRecommender() {
}
<lineannotation>// ...</lineannotation>
}</programlisting>
</section>
<section id="beans-postconstruct-and-predestroy-annotations">
<title><interfacename>@PostConstruct</interfacename> and
<interfacename>@PreDestroy</interfacename></title>
<para>The <classname>CommonAnnotationBeanPostProcessor</classname> not
only recognizes the <interfacename>@Resource</interfacename> annotation
but also the JSR-250 <emphasis>lifecycle</emphasis> annotations.
Introduced in Spring 2.5, the support for these annotations offers yet
another alternative to those described in the sections on <link
linkend="beans-factory-lifecycle-initializingbean">initialization
callbacks</link> and <link
linkend="beans-factory-lifecycle-disposablebean">destruction
callbacks</link>. Provided that the
<classname>CommonAnnotationBeanPostProcessor</classname> is registered
within the Spring <interfacename>ApplicationContext</interfacename>, a
method carrying one of these annotations will be invoked at the same
point in the lifecycle as the corresponding Spring lifecycle interface's
method or explicitly declared callback method. In the example below, the
cache will be pre-populated upon initialization and cleared upon
destruction.</para>
<programlisting language="java">public class CachingMovieLister {
@PostConstruct
public void populateMovieCache() {
<lineannotation>// populates the movie cache upon initialization...</lineannotation>
}
@PreDestroy
public void clearMovieCache() {
<lineannotation>// clears the movie cache upon destruction...</lineannotation>
}
}</programlisting>
<note>
<para>For details regarding the effects of combining various lifecycle
mechanisms, see <xref
linkend="beans-factory-lifecycle-combined-effects" />.</para>
</note>
</section>
</section>
<section id="beans-classpath-scanning">
<title>Classpath scanning, managed components and writing configurations
using Java</title>
<para>Thus far most of the examples within this chapter have used XML for
specifying the configuration metadata that produces each
<interfacename>BeanDefinition</interfacename> within the Spring container.
The previous section (<xref linkend="beans-annotation-config" />)
demonstrated the possibility of providing a considerable amount of the
configuration metadata using source-level annotations. Even in those
examples however, the "base" bean definitions were explicitly defined in
the XML file while the annotations were driving the dependency injection
only. The current section introduces an option for implicitly detecting
the <emphasis>candidate components</emphasis> by scanning the classpath
and matching against <emphasis>filters</emphasis>.</para>
<note>
<para>Starting with Spring 3.0 many of the features provided by the
<ulink url="http://www.springsource.org/javaconfig">Spring JavaConfig
project</ulink> have been added to the core Spring Framework. This
allows you to define beans using Java rather than using the traditional
XML files. Take a look at the
<interfacename>@Configuration</interfacename>, <interfacename>@Bean,
@Import</interfacename> and <interfacename>@DependsOn</interfacename>
annotations for how to use these new features.</para>
</note>
<section id="beans-stereotype-annotations">
<title><interfacename>@Component</interfacename> and further stereotype
annotations</title>
<para>Beginning with Spring 2.0, the
<interfacename>@Repository</interfacename> annotation was introduced as
a marker for any class that fulfills the role or
<emphasis>stereotype</emphasis> of a repository (a.k.a. Data Access
Object or DAO). Among the possibilities for leveraging such a marker is
the automatic translation of exceptions as described in <xref
linkend="orm-jpa-exceptions" />.</para>
<para>Spring 2.5 introduces further stereotype annotations:
<interfacename>@Component</interfacename>,
<interfacename>@Service</interfacename> and
<interfacename>@Controller</interfacename>.
<interfacename>@Component</interfacename> serves as a generic stereotype
for any Spring-managed component; whereas,
<interfacename>@Repository</interfacename>,
<interfacename>@Service</interfacename>, and
<interfacename>@Controller</interfacename> serve as specializations of
<interfacename>@Component</interfacename> for more specific use cases
(e.g., in the persistence, service, and presentation layers,
respectively). What this means is that you can annotate your component
classes with <interfacename>@Component</interfacename>, but by
annotating them with <interfacename>@Repository</interfacename>,
<interfacename>@Service</interfacename>, or
<interfacename>@Controller</interfacename> instead, your classes are
more properly suited for processing by tools or associating with
aspects. For example, these stereotype annotations make ideal targets
for pointcuts. Of course, it is also possible that
<interfacename>@Repository</interfacename>,
<interfacename>@Service</interfacename>, and
<interfacename>@Controller</interfacename> may carry additional
semantics in future releases of the Spring Framework. Thus, if you are
making a decision between using
<interfacename>@Component</interfacename> or
<interfacename>@Service</interfacename> for your service layer,
<interfacename>@Service</interfacename> is clearly the better choice.
Similarly, as stated above, <interfacename>@Repository</interfacename>
is already supported as a marker for automatic exception translation in
your persistence layer.</para>
</section>
<section id="beans-scanning-autodetection">
<title>Auto-detecting components</title>
<para>Spring provides the capability of automatically detecting
'stereotyped' classes and registering corresponding
<interfacename>BeanDefinition</interfacename>s with the
<interfacename>ApplicationContext</interfacename>. For example, the
following two classes are eligible for such autodetection:</para>
<programlisting language="java">@Service
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Autowired
public SimpleMovieLister(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
}</programlisting>
<programlisting language="java">@Repository
public class JpaMovieFinder implements MovieFinder {
<lineannotation>// implementation elided for clarity</lineannotation>
}</programlisting>
<para>To autodetect these classes and register the corresponding beans
requires the inclusion of the following element in XML where
'basePackage' would be a common parent package for the two classes (or
alternatively a comma-separated list could be specified that included
the parent package of each class).</para>
<programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"&gt;
&lt;context:component-scan base-package="org.example"/&gt;
&lt;/beans&gt;</programlisting>
<note>
<para>Note that the scanning of classpath packages requires the
presence of corresponding directory entries in the classpath. When
building jars with Ant, make sure to <emphasis>not</emphasis> activate
the files-only switch of the jar task!</para>
</note>
<para>Furthermore, the
<interfacename>AutowiredAnnotationBeanPostProcessor</interfacename> and
<interfacename>CommonAnnotationBeanPostProcessor</interfacename> are
both included implicitly when using the component-scan element. That
means that the two components are autodetected <emphasis>and</emphasis>
wired together - all without any bean configuration metadata provided in
XML.</para>
<note>
<para>The registration of those post-processors can be disabled by
including the <emphasis>annotation-config</emphasis> attribute with a
value of 'false'.</para>
</note>
</section>
<section id="beans-scanning-filters">
<title>Using filters to customize scanning</title>
<para>By default, classes annotated with
<interfacename>@Component</interfacename>,
<interfacename>@Repository</interfacename>,
<interfacename>@Service</interfacename>, or
<interfacename>@Controller</interfacename> (or classes annotated with a
custom annotation that itself is annotated with
<interfacename>@Component</interfacename>) are the only detected
candidate components. However it is simple to modify and extend this
behavior by applying custom filters. These can be added as either
<emphasis>include-filter</emphasis> or
<emphasis>exclude-filter</emphasis> sub-elements of the
'<literal>component-scan</literal>' element. Each filter element
requires the '<literal>type</literal>' and
'<literal>expression</literal>' attributes. Five filtering options exist
as described below.</para>
<table id="beans-scanning-filters-tbl">
<title>Filter Types</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="1*" />
<colspec colname="c2" colwidth="3*" />
<colspec colname="c" colwidth="4*" />
<thead>
<row>
<entry>Filter Type</entry>
<entry>Example Expression</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>annotation</entry>
<entry><literal>org.example.SomeAnnotation</literal></entry>
<entry>An annotation to be present at the type level in target
components.</entry>
</row>
<row>
<entry>assignable</entry>
<entry><literal>org.example.SomeClass</literal></entry>
<entry>A class (or interface) that the target components are
assignable to (extend/implement).</entry>
</row>
<row>
<entry>aspectj</entry>
<entry><literal>org.example..*Service+</literal></entry>
<entry>An AspectJ type expression to be matched by the target
components.</entry>
</row>
<row>
<entry>regex</entry>
<entry><literal>org\.example\.Default.*</literal></entry>
<entry>A regex expression to be matched by the target
components' class names.</entry>
</row>
<row>
<entry>custom</entry>
<entry><literal>org.example.MyCustomTypeFilter</literal></entry>
<entry>A custom implementation of the
<interfacename>org.springframework.core.type.TypeFilter</interfacename>
interface.</entry>
</row>
</tbody>
</tgroup>
</table>
<para>Find below an example of the XML configuration for ignoring all
<interfacename>@Repository</interfacename> annotations and using "stub"
repositories instead.</para>
<programlisting language="xml">&lt;beans ...&gt;
&lt;context:component-scan base-package="org.example"&gt;
&lt;context:include-filter type="regex" expression=".*Stub.*Repository"/&gt;
&lt;context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/&gt;
&lt;/context:component-scan&gt;
&lt;/beans&gt;</programlisting>
<note>
<para>It is also possible to disable the default filters by providing
<emphasis>use-default-filters="false"</emphasis> as an attribute of
the &lt;component-scan/&gt; element. This will in effect disable
automatic detection of classes annotated with
<interfacename>@Component</interfacename>,
<interfacename>@Repository</interfacename>,
<interfacename>@Service</interfacename>, or
<interfacename>@Controller</interfacename>.</para>
</note>
</section>
<section id="beans-javaconfig-configuration-annotation">
<title>Using the <interfacename>@Configuration</interfacename>
annotation</title>
<para>The central artifact in Spring's new Java-configuration support is
the <interfacename>@Configuration</interfacename>-annotated class. These
classes consist principally of
<interfacename>@Bean</interfacename>-annotated methods that define
instantiation, configuration, and initialization logic for objects that
will be managed by the Spring IoC container.</para>
<para>Annotating a class with the
<interfacename>@Configuration</interfacename> indicates that the class
may be used by the Spring IoC container as a source of bean definitions.
The simplest possible <interfacename>@Configuration</interfacename>
class would read as follows: <programlisting language="java">@Configuration
public class AppConfig {
} </programlisting></para>
<para>An application may make use of one
<interfacename>@Configuration</interfacename>-annotated class, or many.
<interfacename>@Configuration</interfacename> is meta-annotated as a
<interfacename>@Component</interfacename>, therefore
Configuration-classes are candidates for component-scanning and may also
take advantage of <interfacename>@Autowired</interfacename> annotations
at the field and method level but not at the constructor level.
Configuration-classes must also have a default constructor. Externalized
values may be wired into Configuration-classes using the
<interfacename>@Value</interfacename> annotation.</para>
</section>
<section id="beans-javaconfig-bean-annotation">
<title>Using the <interfacename>@Bean</interfacename> annotation</title>
<para><interfacename>@Bean</interfacename> is a method-level annotation
and a direct analog of the XML <code>&lt;bean/&gt;</code> element. The
annotation supports some of the attributes offered by
<code>&lt;bean/&gt;</code>, such as: <code><link
linkend="beans-factory-lifecycle-initializingbean">init-method</link></code>,
<code><link
linkend="beans-factory-lifecycle-disposablebean">destroy-method</link></code>,
<code><link linkend="beans-factory-autowire">autowiring</link></code>
and <code><link
linkend="beans-factory-scopes">name</link></code>.</para>
<para>You can use the @Bean annotation in a Configuraton-class or in a
Component-class.</para>
<section id="beans-javaconfig-declaring-a-bean">
<title>Declaring a bean</title>
<para>To declare a bean, simply annotate a method with the
<interfacename>@Bean</interfacename> annotation. Such a method will be
used to register a bean definition within a <code>BeanFactory</code>
of the type specified as the methods return value. By default, the
bean name will be the same as the method name (see <link
linkend="bean-naming"> bean naming</link> for details on how to
customize this behavior). The following is a simple example of a
<interfacename>@Bean</interfacename> method declaration:
<programlisting language="java">@Configuration
public class AppConfig {
@Bean
public TransferService transferService() {
return new TransferServiceImpl();
}
} </programlisting></para>
<para>For comparison sake, the configuration above is exactly
equivalent to the following Spring XML: <programlisting
language="xml">&lt;beans&gt;
&lt;bean name="transferService" class="com.acme.TransferServiceImpl"/&gt;
&lt;/beans&gt; </programlisting></para>
<para>Both will result in a bean named <code>transferService</code>
being available in the <code>BeanFactory</code> or
<code>ApplicationContext</code>, bound to an object instance of type
<code>TransferServiceImpl</code>: <programlisting>
transferService -&gt; com.acme.TransferServiceImpl
</programlisting></para>
</section>
<section id="beans-javaconfig-injecting-dependencies">
<title>Injecting dependencies</title>
<para>When <interfacename>@Bean</interfacename>s have dependencies on
one another, expressing that dependency is as simple as having one
bean method call another: <programlisting language="java">@Configuration
public class AppConfig {
@Bean
public Foo foo() {
return new Foo(bar());
}
@Bean
public Bar bar() {
return new Bar();
}
} </programlisting></para>
<para>In the example above, the <code>foo</code> bean recevies a
reference to <code> bar</code> via constructor injection.</para>
</section>
<section id="beans-javaconfig-lifecycle-callbacks">
<title>Receiving lifecycle callbacks</title>
<para>Beans created in a Configuration-class supports the regular
lifecycle callbacks. Any classes defined with the @Bean annotation can
use the @PostConstruct and @PreDestroy annotations from JSR-250, see
the section on <link
linkend="beans-factory-lifecycle-combined-effects">JSR-250
annotations</link> for further details.</para>
<para>The regular Spring <link
linkend="beans-factory-nature">lifecycle</link> callbacks are fully
supported as well. If a bean implements <code>InitializingBean</code>,
<code>DisposableBean</code>, or <code>Lifecycle</code>, their
respective methods will be called by the container.</para>
<para>The standard set of <code>*Aware</code> interfaces such as
<code><link
linkend="beans-factory-aware-beanfactoryaware">BeanFactoryAware</link></code>,
<code><link
linkend="beans-factory-aware-beannameaware">BeanNameAware</link></code>,
<code><link
linkend="context-functionality-messagesource">MessageSourceAware</link></code>,
<code><link
linkend="context-functionality-events">ApplicationContextAware</link></code>,
etc. are also fully supported.</para>
<para>The <interfacename>@Bean</interfacename> annotation supports
specifying arbitrary initialization and destruction callback methods,
much like Spring XML's <code>init-method</code> and
<code>destroy-method</code> attributes to the <code>bean</code>
element: <programlisting language="java">public class Foo {
public void init() {
// initialization logic
}
}
public class Bar {
public void cleanup() {
// destruction logic
}
}
@Configuration
public class AppConfig {
@Bean(initMethodName = "init")
public Foo foo() {
return new Foo();
}
@Bean(destroyMethodName="cleanup")
public Bar bar() {
return new Bar();
}
}
</programlisting></para>
<para>Of course, in the case of <code>Foo</code> above, it would be
equally as valid to call the <code>init()</code> method directly
during construction: <programlisting language="java">@Configuration
public class AppConfig {
@Bean
public Foo foo() {
Foo foo = new Foo();
foo.init();
return foo;
}
// ...
} </programlisting></para>
<tip>
<para>Remember that because you are working directly in Java, you
can do anything you like with your objects, and do not always need
to rely on the container!</para>
</tip>
</section>
<section id="beans-javaconfig-specifying-bean-scope">
<title>Specifying bean scope</title>
<section id="beans-javaconfig-available-scopes">
<title>Using the <interfacename>@Scope</interfacename>
annotation</title>
<para>You can specify that your beans defined with the
<interfacename>@Bean</interfacename> annotation should have a
specific scope. You can use any of the standard scopes specified in
the <link linkend="beans-factory-scopes">Bean Scopes</link>
section.</para>
<para>The <code>StandardScopes</code> class provides string
constants for each of these four scopes. SINGLETON is the default,
and can be overridden by using the
<interfacename>@Scope</interfacename> annotation: <programlisting
language="java">@Configuration
public class MyConfiguration {
@Bean
@Scope(StandardScopes.PROTOTYPE)
public Encryptor encryptor() {
// ...
}
} </programlisting></para>
</section>
<section id="beans-javaconfig-scoped-proxy">
<title><code>@Scope and scoped-proxy</code></title>
<para>Spring offers a convenient way of working with scoped
dependencies through <link
linkend="beans-factory-scopes-other-injection">scoped
proxies</link>. The easiest way to create such a proxy when using
the XML configuration is the <code>&lt;aop:scoped-proxy/&gt;</code>
element. Configuring your beans in Java with a @Scope annotation
offers equivalent support with the proxyMode attribute. The default
is no proxy (<varname>ScopedProxyMode.NO</varname>) but you can
specify <classname>ScopedProxyMode.TARGET_CLASS</classname> or
<classname>ScopedProxyMode.INTERFACES</classname>.</para>
<para>If we were to port the the XML reference documentation scoped
proxy example (see link above) to our
<interfacename>@Bean</interfacename> using Java, it would look like
the following: <programlisting language="java">// a HTTP Session-scoped bean exposed as a proxy
@Bean
@Scope(value = StandardScopes.SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public UserPreferences userPreferences() {
return new UserPreferences();
}
@Bean
public Service userService() {
UserService service = new SimpleUserService();
// a reference to the proxied 'userPreferences' bean
service.seUserPreferences(userPreferences());
return service;
} </programlisting></para>
</section>
<section id="beans-javaconfig-method-injection">
<title>Lookup method injection</title>
<para>As noted earlier, <link
linkend="beans-factory-method-injection">lookup method
injection</link> is an advanced feature that should be comparatively
rarely used. It is useful in cases where a singleton-scoped bean has
a dependency on a prototype-scoped bean. Using Java for this type of
configuration provides a natural means for implementing this
pattern. <programlisting language="java">public abstract class CommandManager {
public Object process(Object commandState) {
// grab a new instance of the appropriate Command interface
Command command = createCommand();
// set the state on the (hopefully brand new) Command instance
command.setState(commandState);
return command.execute();
}
// okay... but where is the implementation of this method?
protected abstract Command createCommand();
} </programlisting></para>
<para>Using Java-configuration support we can easily create a
subclass of <code>CommandManager</code> where the abstract
<code>createCommand()</code> is overridden in such a way that it
'looks up' a brand new (prototype) command object: <programlisting
language="java">@Bean
@Scope(StandardScopes.PROTOTYPE)
public AsyncCommand asyncCommand() {
AsyncCommand command = new AsyncCommand();
// inject dependencies here as required
return command;
}
@Bean
public CommandManager commandManager() {
// return new anonymous implementation of CommandManager with command() overridden
// to return a new prototype Command object
return new CommandManager() {
protected Command command() {
return asyncCommand();
}
}
} </programlisting></para>
</section>
</section>
<section id="beans-javaconfig-customizing-bean-naming">
<title>Customizing bean naming</title>
<para>By default, Configuration-classes uses a
<interfacename>@Bean</interfacename> method's name as the name of the
resulting bean. This functionality can be overridden, however, using
the <code>name</code> attribute. <programlisting language="java">@Configuration
public class AppConfig {
@Bean(name = "bar")
public Foo foo() {
return new Foo();
}
} </programlisting></para>
</section>
</section>
<section id="beans-factorybeans-annotations">
<title>Defining bean metadata within components</title>
<para>Spring components can also contribute bean definition metadata to
the container. This is done with the same <literal>@Bean</literal>
annotation used to define bean metadata within
<literal>@Configuration</literal> annotated classes. Here is a simple
example</para>
<programlisting>@Component
public class FactoryMethodComponent {
@Bean @Qualifier("public")
public TestBean publicInstance() {
return new TestBean("publicInstance");
}
public void DoWork()
{
// Component method implementation omitted
}
}</programlisting>
<para>This class is a Spring component and has application specific code
contained in its <methodname>DoWork</methodname> method. However, it
also contributes a bean definition that has a factory method referring
to the method <methodname>publicInstance</methodname>. The
<literal>@Bean</literal> annotation identifies the factory method and
also other bean definition properties, such as a qualifier value via the
<classname>@Qualifier</classname> annotation. Other method level
annotations that can be specified are <literal>@Scope</literal>,
<literal>@Lazy</literal>, and custom qualifier annotations. Autowired
fields and methods are supported as before with the additional support
for autowiring of @Bean methods, as shown in the example below</para>
<programlisting language="java">@Component
public class FactoryMethodComponent {
private static int i;
@Bean @Qualifier("public")
public TestBean publicInstance() {
return new TestBean("publicInstance");
}
// use of a custom qualifier and autowiring of method parameters
@Bean @BeanAge(1)
protected TestBean protectedInstance(@Qualifier("public") TestBean spouse, @Value("#{privateInstance.age}") String country) {
TestBean tb = new TestBean("protectedInstance", 1);
tb.setSpouse(tb);
tb.setCountry(country);
return tb;
}
@Bean @Scope(StandardScopes.PROTOTYPE)
private TestBean privateInstance() {
return new TestBean("privateInstance", i++);
}
@Bean @Scope(value = StandardScopes.SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public TestBean requestScopedInstance() {
return new TestBean("requestScopedInstance", 3);
}
}
</programlisting>
<para>Note the use of autowiring of the <classname>String</classname>
method parameter <literal>country</literal> to the value of the
<literal>Age</literal> property on another bean named
<literal>privateInstance</literal>. A Spring Expression Language element
is used to define the value of the property via the notation <literal>#{
&lt;expression&gt; }</literal>. For <literal>@Value</literal>
annotations, an expression resolver is preconfigured to look for bean
names when resolving expression text.</para>
<para>The <literal>@Bean</literal> methods in a Spring component are
processed differently than their counterparts inside a Spring
<literal>@Configuration</literal> class. The difference is that
<literal>@Component</literal> classes are not enhanced with CGLIB to
intercept the invocation of methods and fields. CGLIB proxying is the
means by which invoking methods or fields within
<literal>@Configuration</literal> classes' <literal>@Bean</literal>
methods create bean metadata references to collaborating objects and do
<emphasis>not</emphasis> invoke the method with normal Java semantics.
In contrast, calling a method or field within a
<literal>@Component</literal> classes' <literal>@Bean</literal> method
<emphasis>has</emphasis> standard Java semantics.</para>
</section>
<section id="beans-scanning-name-generator">
<title>Naming autodetected components</title>
<para>When a component is autodetected as part of the scanning process,
its bean name will be generated by the
<interfacename>BeanNameGenerator</interfacename> strategy known to that
scanner. By default, any Spring 'stereotype' annotation
(<interfacename>@Component</interfacename>,
<interfacename>@Repository</interfacename>,
<interfacename>@Service</interfacename>, and
<interfacename>@Controller</interfacename>) that contains a
<literal>name</literal> value will thereby provide that name to the
corresponding bean definition. If such an annotation contains no
<literal>name</literal> value or for any other detected component (such
as those discovered due to custom filters), the default bean name
generator will return the uncapitalized non-qualified class name. For
example, if the following two components were detected, the names would
be 'myMovieLister' and 'movieFinderImpl':</para>
<programlisting language="java">@Service("myMovieLister")
public class SimpleMovieLister {
<lineannotation>// ...</lineannotation>
}</programlisting>
<programlisting language="java">@Repository
public class MovieFinderImpl implements MovieFinder {
<lineannotation>// ...</lineannotation>
}</programlisting>
<note>
<para>If you don't want to rely on the default bean-naming strategy,
you may provide a custom bean-naming strategy. First, implement the
<ulink
url="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/beans/factory/support/BeanNameGenerator.html"><interfacename>BeanNameGenerator</interfacename></ulink>
interface, and be sure to include a default no-arg constructor. Then,
provide the fully-qualified class name when configuring the
scanner:</para>
</note>
<programlisting language="xml">&lt;beans ...&gt;
&lt;context:component-scan base-package="org.example"
name-generator="org.example.MyNameGenerator" /&gt;
&lt;/beans&gt;</programlisting>
<para>As a general rule, consider specifying the name with the
annotation whenever other components may be making explicit references
to it. On the other hand, the auto-generated names are adequate whenever
the container is responsible for wiring.</para>
</section>
<section id="beans-scanning-scope-resolver">
<title>Providing a scope for autodetected components</title>
<para>As with Spring-managed components in general, the default and by
far most common scope is 'singleton'. However, there are times when
other scopes are needed. Therefore Spring 2.5 introduces a new
<interfacename>@Scope</interfacename> annotation as well. Simply provide
the name of the scope within the annotation, such as:</para>
<programlisting language="java">@Scope(StandardScopes.PROTOTYPE)
@Repository
public class MovieFinderImpl implements MovieFinder {
<lineannotation>// ...</lineannotation>
}</programlisting>
<note>
<para>If you would like to provide a custom strategy for scope
resolution rather than relying on the annotation-based approach,
implement the <ulink
url="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/context/annotation/ScopeMetadataResolver.html"><interfacename>ScopeMetadataResolver</interfacename></ulink>
interface, and be sure to include a default no-arg constructor. Then,
provide the fully-qualified class name when configuring the
scanner:</para>
</note>
<programlisting language="xml">&lt;beans ...&gt;
&lt;context:component-scan base-package="org.example"
scope-resolver="org.example.MyScopeResolver" /&gt;
&lt;/beans&gt;</programlisting>
<para>When using certain non-singleton scopes, it may be necessary to
generate proxies for the scoped objects. The reasoning is described in
detail within the section entitled <xref
linkend="beans-factory-scopes-other-injection" />. For this purpose, a
<emphasis>scoped-proxy</emphasis> attribute is available on the
'component-scan' element. The three possible values are: 'no',
'interfaces', and 'targetClass'. For example, the following
configuration will result in standard JDK dynamic proxies:</para>
<programlisting language="xml">&lt;beans ...&gt;
&lt;context:component-scan base-package="org.example"
scoped-proxy="interfaces" /&gt;
&lt;/beans&gt;</programlisting>
</section>
<section id="beans-scanning-qualifiers">
<title>Providing qualifier metadata with annotations</title>
<para>The <interfacename>@Qualifier</interfacename> annotation was
introduced in the section above entitled <xref
linkend="beans-autowired-annotation-qualifiers" />. The examples in that
section demonstrated use of the
<interfacename>@Qualifier</interfacename> annotation as well as custom
qualifier annotations to provide fine-grained control when resolving
autowire candidates. Since those examples were based on XML bean
definitions, the qualifier metadata was provided on the candidate bean
definitions using the '<literal>qualifier</literal>' or
'<literal>meta</literal>' sub-elements of the '<literal>bean</literal>'
element in the XML. When relying upon classpath scanning for
autodetection of components, then the qualifier metadata may be provided
with type-level annotations on the candidate class. The following three
examples demonstrate this technique.</para>
<programlisting language="java">@Component
<emphasis role="bold">@Qualifier("Action")</emphasis>
public class ActionMovieCatalog implements MovieCatalog {
<lineannotation>// ...</lineannotation>
}</programlisting>
<programlisting language="java">@Component
<emphasis role="bold">@Genre("Action")</emphasis>
public class ActionMovieCatalog implements MovieCatalog {
<lineannotation>// ...</lineannotation>
}</programlisting>
<programlisting language="java">@Component
<emphasis role="bold">@Offline</emphasis>
public class CachingMovieCatalog implements MovieCatalog {
<lineannotation>// ...</lineannotation>
}</programlisting>
<note>
<para>As with most of the annotation-based alternatives, keep in mind
that the annotation metadata is bound to the class definition itself,
while the use of XML allows for multiple beans <emphasis>of the same
type</emphasis> to provide variations in their qualifier metadata
since that metadata is provided per-instance rather than
per-class.</para>
</note>
</section>
</section>
<section id="context-load-time-weaver">
<title>Registering a <interfacename>LoadTimeWeaver</interfacename></title>
<para>The <literal>context</literal> namespace introduced in Spring 2.5
provides a <literal>load-time-weaver</literal> element.</para>
<programlisting language="xml">&lt;beans ...&gt;
&lt;context:load-time-weaver/&gt;
&lt;/beans&gt;</programlisting>
<para>Adding this element to an XML-based Spring configuration file
activates a Spring <interfacename>LoadTimeWeaver</interfacename> for the
<interfacename>ApplicationContext</interfacename>. Any bean within that
<interfacename>ApplicationContext</interfacename> may implement
<interfacename>LoadTimeWeaverAware</interfacename> thereby receiving a
reference to the load-time weaver instance. This is particularly useful in
combination with <link linkend="orm-jpa">Spring's JPA support</link> where
load-time weaving may be necessary for JPA class transformation. Consult
the <classname>LocalContainerEntityManagerFactoryBean</classname> Javadoc
for more detail. For more on AspectJ load-time weaving, see <xref
linkend="aop-aj-ltw" />.</para>
</section>
</chapter>