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

6624 lines
316 KiB
XML
Raw Normal View History

<?xml version="1.0" encoding="UTF-8"?>
2009-04-30 05:14:01 +08:00
<!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">
2009-07-01 23:24:04 +08:00
<title>Introduction to the Spring IoC container and beans</title>
2009-07-01 23:24:04 +08:00
<para>This chapter covers the Spring Framework 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
2009-07-01 23:24:04 +08:00
<literal>org.springframework.context</literal> packages are the basis for
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
any type of object. <literal><ulink
url="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/context/ApplicationContext.html">ApplicationContext</ulink></literal>
2009-07-01 23:24:04 +08:00
is a sub-interface of <interfacename>BeanFactory.</interfacename> It adds
easier integration with Spring's AOP features; message resource handling
2009-07-16 11:17:53 +08:00
(for use in internationalization), event publication; and
application-layer specific contexts such as the
2009-07-01 23:24:04 +08:00
<interfacename>WebApplicationContext</interfacename> for use in web
applications.</para>
<para>In short, the <interfacename>BeanFactory</interfacename> provides
2009-07-01 23:24:04 +08:00
the configuration framework and basic functionality, and the
<interfacename>ApplicationContext</interfacename> adds more
2009-07-01 23:24:04 +08:00
enterprise-specific functionality. The
<interfacename>ApplicationContext</interfacename> is a complete superset
of the <interfacename>BeanFactory</interfacename>, and is used exclusively
in this chapter in descriptions of Spring's IoC container. <!--API spec says ApplicationContext is a subinterface of BeanFactory, so is it right to call it a superset?-->For
more information on using the <classname>BeanFactory</classname> instead
of the <classname>ApplicationContext,</classname> refer to <xref
linkend="beans-beanfactory" />.</para>
2009-07-01 23:24:04 +08:00
<para>In Spring, the objects that form the backbone of your application
and that are managed by the Spring IoC <firstterm>container</firstterm>
are called <firstterm>beans</firstterm>. A bean is an object that is
instantiated, assembled, and otherwise managed by a Spring IoC container.
Otherwise, a bean is simply one of many objects in your application.
Beans, and the <firstterm>dependencies</firstterm> between them, are
reflected in the <firstterm>configuration metadata</firstterm> used by a
container.</para>
</section>
2009-07-16 11:17:53 +08:00
<section id="beans-basics">
<title>Container overview</title>
2009-07-01 23:24:04 +08:00
<para>The interface
<classname>org.springframework.context.ApplicationContext</classname>
represents the Spring IoC container and is responsible for instantiating,
configuring, and assembling the aforementioned beans. The container gets
its instructions on what objects to instantiate, configure, and assemble
by reading configuration metadata. The configuration metadata is
represented in XML, Java annotations, or Java code. It allows you to
express the objects that compose your application and the rich
interdependencies between such objects.</para>
<para>Several implementations of the
<classname>ApplicationContext</classname> interface are supplied
out-of-the-box with Spring. In standalone applications it is common to create an
2009-07-16 11:17:53 +08:00
instance of <ulink
2009-07-01 23:24:04 +08:00
url="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/context/support/ClassPathXmlApplicationContext.html"><classname>ClassPathXmlApplicationContext</classname></ulink>
or <ulink
url="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/context/support/FileSystemXmlApplicationContext.html"><classname>FileSystemXmlApplicationContext</classname></ulink>.
2009-07-16 11:17:53 +08:00
While XML has been the traditional format for defining configuration
metadata you instruct the container to use Java annotations or code as the
metadata format by providng a small amount of XML configuration to
declaratively enable support for using these additional metadata
formats.</para>
2009-07-01 23:24:04 +08:00
<para>In most 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
2009-07-16 11:17:53 +08:00
linkend="context-create" />). If you are using the <ulink
url="http://www.springsource.com/produts/sts">SpringSource Tool
Suite</ulink> Eclipse-powered development environment or <ulink
url="http://www.springsource.org/roo">Spring Roo</ulink> this boilerplate
configuration can be easily created with few mouse clicks or
keystrokes.</para>
2009-07-01 23:24:04 +08:00
<para>The following diagram is a high-level view of how Spring works. Your
application classes are combined with configuration metadata so that after
the <classname>ApplicationContext</classname> is created and initialized,
you have a fully configured and executable system or application.</para>
<para><mediaobject>
2009-07-16 11:17:53 +08:00
<imageobject>
2009-07-01 23:24:04 +08:00
<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 the preceding diagram shows, the Spring IoC container consumes
a form of <emphasis>configuration metadata</emphasis>; this
configuration metadata represents how you as an application developer
tell the Spring container to instantiate, configure, and assemble the
2009-07-16 11:17:53 +08:00
objects in your application.</para>
2009-07-01 23:24:04 +08:00
<para>Configuration metadata is traditionally supplied in a simple and
intuitive XML format, which is what most of this chapter uses to convey
key concepts and features of the Spring IoC container.</para>
2009-07-01 23:24:04 +08:00
<note>
<para>XML-based metadata is <emphasis>not</emphasis> the only allowed
form of configuration metadata. The Spring IoC container itself is
<emphasis>totally</emphasis> decoupled from the format in which this
configuration metadata is actually written.</para>
</note>
2009-07-01 23:24:04 +08:00
<para>For information about using other forms of metadata with the
Spring container, see:</para>
2009-07-01 23:24:04 +08:00
<itemizedlist>
<listitem>
<para><link linkend="beans-annotation-config">Annotation-based
configuration</link>: Spring 2.5 introduced support for
annotation-based configuration metadata.</para>
</listitem>
2009-07-01 23:24:04 +08:00
<listitem>
<para><link linkend="beans-javaconfig">Java-based
configuration</link>: Starting with Spring 3.0, many features
provided by the <ulink
url="http://www.springsource.org/javaconfig">Spring JavaConfig
project</ulink> became part of the core Spring Framework. Thus you
can define beans external to your application classes by using Java
rather than XML files. To use these new features, see the
<interfacename>@Configuration</interfacename>, <interfacename>@Bean,
@Import</interfacename> and
<interfacename>@DependsOn</interfacename> annotations.</para>
</listitem>
</itemizedlist>
2009-07-01 23:24:04 +08:00
<para>Spring configuration consists of at least one and typically more
configuration metadata shows these beans configured as
<literal>&lt;bean/&gt;</literal> elements inside a top-level
<literal>&lt;beans/&gt;</literal> element.</para>
2009-07-01 23:24:04 +08:00
<para>These bean definitions correspond to the actual objects that make
up your application. Typically you define service layer objects, 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 and
load domain objects. However, you can use Spring's integration with
AspectJ to configure objects that have been created outside the control
of an IoC container. See <link linkend="aop-atconfigurable">Using
AspectJ to dependency inject domain objects with Spring</link>.</para>
<para>The following example shows 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>
2009-07-01 23:24:04 +08:00
<para>The <literal>id</literal> attribute is a string that you use to
identify the individual bean definition. The <literal>class</literal>
attribute defines the type of the bean and uses the fully qualified
classname. The value of the id attribute refers to collaborating
objects. The XML for referring to collaborating objects is not shown in
this example; see <link linkend="beans-dependencies">Dependencies</link>
for more information.</para>
</section>
<section id="beans-factory-instantiation">
<title>Instantiating a container</title>
2009-07-01 23:24:04 +08:00
<para>Instantiating a Spring IoC container is straightforward. 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>, and so on.</para>
2009-07-16 11:17:53 +08:00
<programlisting language="java">ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"services.xml",
"daos.xml"});</programlisting>
<note>
2009-07-01 23:24:04 +08:00
<para>After you learn about Spring's IoC container, you may want to
know more about Spring's <interfacename>Resource</interfacename>
2009-07-16 11:17:53 +08:00
abstraction, as described in <xref linkend="resources" />, which
provides a convenient mechanism for reading an InputSream from
locations defined in a URI syntax. In particular, the use of
<classname>Resource</classname> paths to construct applications
contexts as described in <xref linkend="resources-app-ctx" />. </para>
</note>
2009-07-01 23:24:04 +08:00
<para>The following example shows the service layer objects
<literal>(services.xml)</literal> configuration file:</para>
<programlisting>&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;!-- services --&gt;
2009-07-16 11:17:53 +08:00
&lt;bean id="petStore"
class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl"&gt;
&lt;property name="accountDao" ref="accountDao"/&gt;
&lt;property name="itemDao" ref="itemDao"/&gt;
&lt;!-- additional collaborators and configuration for this bean go here --&gt;
&lt;/bean&gt;
&lt;!-- more bean definitions for services go here --&gt;
&lt;/beans&gt;
</programlisting>
2009-07-01 23:24:04 +08:00
<para>The following example shows the data access objects
2009-07-16 11:17:53 +08:00
<literal>(daos.xml</literal>) configuration file:</para>
<programlisting>&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="accountDao" class="org.springframework.samples.jpetstore.dao.ibatis.SqlMapAccountDao"&gt;
&lt;!-- additional collaborators and configuration for this bean go here --&gt;
&lt;/bean&gt;
&lt;bean id="itemDao" class="org.springframework.samples.jpetstore.dao.ibatis.SqlMapItemDao"&gt;
&lt;!-- additional collaborators and configuration for this bean go here --&gt;
&lt;/bean&gt;
&lt;!-- more bean definitions for data access objects go here --&gt;
&lt;/beans&gt;</programlisting>
<para>In the preceding example, the service layer consists of the class
2009-07-01 23:24:04 +08:00
<classname>PetStoreServiceImpl</classname>, and two data access objects
of the type <classname>SqlMapAccountDao</classname> and SqlMapItemDao
are based on the <ulink url="http://ibatis.apache.org/">iBatis</ulink>
Object/Relational mapping framework. The <literal>property
name</literal> element refers to the name of the JavaBean property, and
the <literal>ref</literal> element refers to the name of another bean
definition. This linkage between id and ref elements expresses the
dependency between collaborating objects. For details of configuring an
object's dependencies, see <link
linkend="beans-dependencies">Dependencies</link>.</para>
<section id="beans-factory-xml-import">
<title>Composing XML-based configuration metadata</title>
<para>It can be useful to have bean definitions span multiple XML
2009-07-01 23:24:04 +08:00
files. Often each individual XML configuration file represents a
logical layer or module in your architecture.</para>
<para>You can use the application context constructor to load bean
definitions from all these XML fragments.
This constructor takes multiple
<interfacename>Resource</interfacename> locations, as was shown in the
previous section. Alternatively, use one or more occurrences of the
<literal>&lt;import/&gt;</literal> element to load bean definitions
from another file or files. For example:</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 the preceding example, external bean definitions are loaded
from three files, <literal>services.xml</literal>,
<literal>messageSource.xml</literal>, and
<literal>themeSource.xml</literal>. All location paths are relative to
the definition file doing the importing, so
<literal>services.xml</literal> 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 ignored, but given
that these paths are relative, it is better form not to use the slash
at all. The contents of the files being imported, including the top
level <literal>&lt;beans/&gt;</literal> element, must be valid XML
bean definitions according to the Spring Schema or DTD.</para>
<note>
2009-07-01 23:24:04 +08:00
<para>It is possible, but not recommended, to reference files in
parent directories using a relative "../" path. Doing so creates a
dependency on a file that is outside the current application. In
particular, this reference is not recommended for "classpath:" URLs
(for example, "classpath:../services.xml"), where the runtime
resolution process chooses the "nearest" classpath root and then
looks into its parent directory. Classpath configuration changes may
lead to the choice of a different, incorrect directory.</para>
2009-07-01 23:24:04 +08:00
<para>You can always use fully qualified resource locations instead
of relative paths: for example, "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. It is generally preferable to keep an indirection for
2009-07-16 11:17:53 +08:00
such absolute locations, for example, through <link
linkend="beans-factory-placeholderconfigurer">property
placeholders</link>, "${...}", that are resolved against externally
defined properties at runtime.</para>
</note>
</section>
</section>
<section id="beans-factory-client">
<title>Using the container</title>
2009-07-01 23:24:04 +08:00
<para>The <interfacename>ApplicationContext</interfacename> is the
interface for an advanced factory capable of maintaining a registry of
different beans and their dependencies. Using the method <methodname>T
getBean(Stringname, Class&lt;T&gt; requiredType)</methodname> you can
retrieve instances of your beans.</para>
<para>The <interfacename>ApplicationContext</interfacename> enables you
2009-07-01 23:24:04 +08:00
to read bean definitions and access them as follows:</para>
<programlisting language="java">// create and configure beans
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"});
// retrieve configured instance
PetStoreServiceImpl service = context.getBean("petStore", PetStoreServiceImpl.class);
// use configured instance
List userList service.getUsernameList();
</programlisting>
<para>You use <methodname>getBean</methodname> to retrieve instances of
your beans. The <interfacename>ApplicationContext</interfacename>
interface has a few other methods for retrieving beans, but ideally your application code
2009-07-16 11:17:53 +08:00
should never use them. Indeed, your application code should have no
calls to the <methodname>getBean</methodname> method at all, and thus no
dependency on Spring APIs at all. For example, Spring's integration with
web frameworks provides for dependency injection for various web
framework classes such as controllers and JSF-managed beans.</para>
</section>
2009-07-01 23:24:04 +08:00
</section>
2009-07-01 23:24:04 +08:00
<section id="beans-definition">
<title>Bean overview</title>
2009-07-01 23:24:04 +08:00
<para>A Spring IoC container manages one or more
<emphasis>beans</emphasis>. These beans are created with the
2009-07-16 11:17:53 +08:00
configuration metadata that you supply to the container, for example, in
the form of XML <literal>&lt;bean/&gt;</literal> definitions.</para>
2009-07-01 23:24:04 +08:00
<para>Within the container itself, these bean definitions are represented
as <interfacename>BeanDefinition</interfacename> objects, which contain
(among other information) the following metadata:</para>
2009-07-01 23:24:04 +08:00
<itemizedlist>
<listitem>
<para><emphasis>A package-qualified class name:</emphasis> typically
the actual implementation class of the bean being defined.</para>
</listitem>
2009-07-01 23:24:04 +08:00
<listitem>
<para>Bean behavioral configuration elements, which state how the bean
should behave in the container (scope, lifecycle callbacks, and so
forth).</para>
</listitem>
2009-07-01 23:24:04 +08:00
<listitem>
<para>References to other beans that are needed for the bean to do its
work; these references are also called
<emphasis>collaborators</emphasis> or
<emphasis>dependencies</emphasis>.</para>
</listitem>
2009-07-01 23:24:04 +08:00
<listitem>
<para>Other configuration settings to set in the newly created object,
for example, 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>This metadata translates to a set of properties that make up each
bean definition. The following table lists some of
2009-07-01 23:24:04 +08:00
these properties, with links to documentation</para>
2009-07-01 23:24:04 +08:00
<table id="beans-factory-bean-definition-tbl">
<title>The bean definition</title>
2009-07-01 23:24:04 +08:00
<tgroup cols="2">
<colspec colname="c1" colwidth="2*" />
2009-07-01 23:24:04 +08:00
<colspec colname="c2" colwidth="4*" />
2009-07-01 23:24:04 +08:00
<thead>
<row>
<entry>Property</entry>
2009-07-01 23:24:04 +08:00
<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>In addition to bean definitions that contain information on how to create a
specific bean, the <interfacename>ApplicationContext</interfacename>
2009-07-01 23:24:04 +08:00
implementations also permit the registration of existing objects that are
2009-07-16 11:17:53 +08:00
created outside the container, by users. This is done by accessing the
ApplicationContext's BeanFactory via the method
<methodname>getBeanFactory</methodname> which returns the BeanFactory
implementation <classname>DefaultListableBeanFactory</classname>.
<classname>DefaultListableBeanFactory</classname> supports this
registration through the methods
<methodname>registerSingleton(..)</methodname> and
<methodname>registerBeanDefinition(..)</methodname>. However, typical
applications work solely with beans defined through metadata bean
definitions. For more information on the relationship between a
<classname>BeanFactory</classname> and the
<classname>ApplicationContext</classname> see <xref
linkend="beans-beanfactory" />.</para>
2009-07-01 23:24:04 +08:00
<section id="beans-beanname">
<title>Naming beans</title>
<para>Every bean has one or more identifiers. These identifiers must be
unique within the container that hosts the bean. A bean usually has only
one identifier, but if it requires more than one, the extra ones can be
considered aliases.</para>
<para>In XML-based configuration metadata, you use the
2009-07-01 23:24:04 +08:00
<literal>id</literal> and/or <literal>name</literal> attributes to
specify the bean identifier(s). The <literal>id</literal> attribute
allows you to specify exactly one id, and because it is a real XML
element ID attribute, the XML parser can do some extra validation when
other elements reference the id. As such, it is the preferred way to
specify a bean identifier. However, the XML specification does limit the
characters that are legal in XML ids. This is usually not a constraint,
but if you need to use one of these special XML characters, or want to
2009-07-16 11:17:53 +08:00
introduce other aliases to the bean, you can also specify them in the
<literal>name</literal> attribute, separated by a comma
2009-07-01 23:24:04 +08:00
(<literal>,</literal>), semicolon (<literal>;</literal>), or white
space.</para>
2009-07-16 11:17:53 +08:00
<para>You are not required to specify a name or id for a bean. If no
name or id is supplied explicitly, the container generates a unique name
for that bean. However, if you want to refer to that bean by name,
through the use of the <literal>ref</literal> element or <link lang=""
linkend="beans-servicelocation">Service Location</link> style lookup,
you must provide a name. Motivations for not
2009-07-16 11:17:53 +08:00
supplying a name are related to using <link
linkend="beans-inner-beans">inner beans</link> and <link
linkend="beans-factory-autowire">autowiring collaborators</link>.</para>
<sidebar>
<title>Bean naming conventions</title>
<para>The convention 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>Naming beans consistently makes your configuration easier to
read and understand, and if you are using Spring AOP it helps a lot
when applying advice to a set of beans related by name.</para>
</sidebar>
2009-07-01 23:24:04 +08:00
<section id="beans-beanname-alias">
<title>Aliasing a bean outside the bean definition</title>
<para>In a bean definition itself, you can supply more than one name
for the bean, by using a combination of up to one name specified by
the <literal>id</literal> attribute, and any number of other names in
the <literal>name</literal> attribute. These names can be equivalent
aliases to the same bean, and are useful for some situations, such as
allowing each component in an application to refer to a common
dependency by using a bean name that is specific to that component
itself.</para>
<para>Specifying all aliases where the bean is actually defined is not
always adequate, however. It is sometimes desirable to introduce an
2009-07-16 11:17:53 +08:00
alias for a bean that is defined elsewhere. This is commonly the case
in large systems where configuration is split amongst each subsystem,
each subsystem having its own set of object defintions. In XML-based
configuration metadata, you can use of the
<literal>&lt;alias/&gt;</literal> element to accomplish this.</para>
2009-07-01 23:24:04 +08:00
<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>
2009-07-01 23:24:04 +08:00
2009-07-16 11:17:53 +08:00
<para>For example, the configuration metadata for subsystem A may
refer to a DataSource via the name 'subsystemA-dataSource. The
configuration metadata for subsystem B may refer to a DataSource via
the name 'subsystemB-dataSource'. When composing the main application
that uses both these subsystems the main application refers to the
DattaSource via the name 'myApp-dataSource'. To have all three names
refer to the same object you add to the MyApp configuration metadata
the following aliases definitions:</para>
2009-07-01 23:24:04 +08:00
2009-07-16 11:17:53 +08:00
<programlisting language="xml">&lt;alias name="subsystemA-dataSource" alias="subsystemB-dataSource"/&gt;
&lt;alias name="subsystemA-dataSource" alias="myApp-dataSource" /&gt;</programlisting>
2009-07-01 23:24:04 +08:00
<para>Now each component and the main application can refer to the
dataSource through a name that is unique and guaranteed not to clash
with any other definition (effectively creating a namespace), yet they
refer to the same bean.</para>
</section>
2009-07-01 23:24:04 +08:00
</section>
2009-07-01 23:24:04 +08:00
<section id="beans-factory-class">
<title>Instantiating beans</title>
<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 use XML-based configuration metadata, you specify the type
(or class) of object that is to be instantiated in the
2009-07-01 23:24:04 +08:00
<literal>class</literal> attribute of the
<literal>&lt;bean/&gt;</literal> element. This <literal>class</literal>
attribute, which internally is a <classname>Class</classname> property
on a <interfacename>BeanDefinition</interfacename> instance, is usually
2009-07-01 23:24:04 +08:00
mandatory. (For exceptions, see <xref
linkend="beans-factory-class-instance-factory-method" /> and <xref
linkend="beans-child-bean-definitions" />.) You use the
<classname>Class</classname> property in one of two ways: <itemizedlist>
<listitem>
<para>Typically, to specify the bean class to be constructed in
the case where the container itself directly creates the bean by
calling its constructor reflectively, somewhat equivalent to Java
code using the <code>new</code> operator.</para>
2009-07-01 23:24:04 +08:00
</listitem>
</itemizedlist></para>
2009-07-01 23:24:04 +08:00
<itemizedlist>
<listitem>
<para>To specify the actual class containing the
<literal>static</literal> factory method that will be invoked to
create the object, 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 object type returned from
the invocation of the <literal>static</literal> factory method may
be the same class or another class entirely.</para>
2009-07-01 23:24:04 +08:00
</listitem>
</itemizedlist>
2009-07-16 11:17:53 +08:00
<sidebar>
<title>Inner class names</title>
<para>If 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>
2009-07-01 23:24:04 +08:00
<section id="beans-factory-class-ctor">
<title>Instantiation with a constructor</title>
2009-07-01 23:24:04 +08:00
<para>When you create a bean by the constructor approach, all normal
classes are usable by and compatible with Spring. That is, the class
being developed does not need to implement any specific interfaces or to be
coded in a specific fashion. Simply specifying the bean class should
suffice. However, depending on what type of IoC you are going to use
2009-07-01 23:24:04 +08:00
for that specific bean, you may need a default (empty)
constructor.</para>
<para>The Spring IoC container can manage virtually
2009-07-01 23:24:04 +08:00
<emphasis>any</emphasis> class you want it to manage; it is not
limited to managing true JavaBeans. Most Spring users prefer actual
JavaBeans with only a default (no-argument) constructor and
2009-07-01 23:24:04 +08:00
appropriate setters and getters modeled after the properties in the
container. You can also 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>
2009-07-01 23:24:04 +08:00
<para>With XML-based configuration metadata you can specify your bean
class as follows:</para>
2009-07-01 23:24:04 +08:00
<programlisting language="xml">&lt;bean id="exampleBean" class="examples.ExampleBean"/&gt;
&lt;bean name="anotherExample" class="examples.ExampleBeanTwo"/&gt;</programlisting>
<para>For details about the mechanism for supplying arguments to the
constructor (if required) and setting object instance properties after
the object is constructed, see <link
2009-07-01 23:24:04 +08:00
linkend="beans-factory-collaborators">Injecting
Dependencies</link>.</para>
</section>
2009-07-01 23:24:04 +08:00
<section id="beans-factory-class-static-factory-method">
<title>Instantiation with a static factory method</title>
2009-07-01 23:24:04 +08:00
<para>When defining a bean that you create with a static factory
method, you use the <literal>class</literal> attribute to specify the
class containing the <literal>static</literal> factory method and an
attribute named <literal>factory-method</literal> to specify the name
of the factory method itself. You should be able to call this method
(with optional arguments as described later) and return a live object,
which subsequently is treated as if it had been created through a
constructor. One use for such a bean definition is to call
<literal>static</literal> factories in legacy code.</para>
<para>The following bean definition specifies that the bean will be
created by calling a factory-method. The definition does not specify
the type (class) of the returned object, only the class containing the
factory method. In this example, the
2009-07-01 23:24:04 +08:00
<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>For details about the mechanism for supplying (optional)
arguments to the factory method and setting object instance properties
after the object is returned from the factory, see <link
2009-07-01 23:24:04 +08:00
linkend="beans-factory-properties-detailed">Dependencies and
configuration in detail</link>.</para>
</section>
2009-07-01 23:24:04 +08:00
<section id="beans-factory-class-instance-factory-method">
<title>Instantiation using an instance factory method</title>
<para>Similar to instantiation through a <link
linkend="beans-factory-class-static-factory-method">static factory
method</link>, instantiation with an instance factory method invokes a
non-static method of an existing bean from the container to create a
new bean. To use this mechanism, leave the <literal>class
</literal>attribute empty, and in the <literal>factory-bean</literal>
attribute, 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. Set the name of the factory method
itself with the <literal>factory-method</literal> attribute.</para>
2009-07-01 23:24:04 +08:00
<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>This approach shows that the factory bean itself can be managed
and configured through dependency injection (DI). See <link
linkend="beans-factory-properties-detailed"><link
linkend="beans-factory-properties-detailed">Dependencies and
configuration in detail</link>.</link></para>
2009-07-01 23:24:04 +08:00
<note>
<para>In Spring documentation,<emphasis> factory bean</emphasis>
refers to a bean that is configured in the Spring container that
will create objects through an <link
linkend="beans-factory-class-instance-factory-method">instance</link>
or <link
linkend="beans-factory-class-static-factory-method">static</link>
factory method. By contrast,
<interfacename>FactoryBean</interfacename> (notice the
capitalization) refers to a Spring-specific <link
linkend="beans-factory-extension-factorybean">
<interfacename>FactoryBean</interfacename> </link>.</para>
</note>
</section>
</section>
</section>
<section id="beans-dependencies">
<title>Dependencies</title>
2009-07-01 23:24:04 +08:00
<para>A typical enterprise application does not consist of a single object
(or bean in the Spring parlance). Even the simplest application has a few
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 to a fully realized application where
objects collaborate to achieve a goal.</para>
<section id="beans-factory-collaborators">
<title>Dependency injection </title>
2009-07-01 23:24:04 +08:00
<para><emphasis>Dependency injection</emphasis> (DI) is a process
whereby objects define their dependencies, that is, the other objects
they work with, only through constructor arguments, arguments to a
factory method, or properties that are set on the object instance after
it is constructed or returned from a factory method. The container then
<emphasis>injects</emphasis> those dependencies when it creates the
2009-07-01 23:24:04 +08:00
bean. This process is fundamentally the inverse, hence the name
<emphasis>Inversion of Control</emphasis> (IoC), of the bean itself
controlling the instantiating or location of its dependencies on its own
2009-07-01 23:24:04 +08:00
by using direct construction of classes, or the <emphasis>Service
Locator</emphasis> pattern.</para>
<para>Code is cleaner with the DI principle and decoupling is more
effective when objects are provided with their dependencies. The object
does not look up its dependencies, and does not know the location or
2009-07-16 11:17:53 +08:00
class of the dependencies. As such, your classes become easier to test,
in particular when the dependencies are on interfaces or abstract base
classes, which allow for stub or mock implementations to be used in unit
tests.</para>
<para>DI exists in two major variants, <link
2009-07-01 23:24:04 +08:00
linkend="beans-constructor-injection">Constructor-based dependency
injection</link> and <link linkend="beans-setter-injection">Setter-based
dependency injection</link>.</para>
<section id="beans-constructor-injection">
2009-07-01 23:24:04 +08:00
<title>Constructor-based dependency injection</title>
2009-07-16 11:17:53 +08:00
<para><emphasis>Constructor-based</emphasis> DI is accomplished by the
container invoking a constructor with a number of arguments, each
representing a dependency. Calling a <literal>static</literal> factory
method with specific arguments to construct the bean is nearly
equivalent, and this discussion treats arguments to a constructor and
to a <literal>static</literal> factory method similarly. The following
example shows a class that can only be dependency-injected with
constructor injection. Notice that there is nothing
2009-07-16 11:17:53 +08:00
<emphasis>special</emphasis> about this class, it is a POJO that has
no dependencies on container specific interfaces, base classes or
annotations.</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">
2009-07-01 23:24:04 +08:00
<title>Constructor argument resolution</title>
<para>Constructor argument resolution matching occurs using the
2009-07-01 23:24:04 +08:00
argument's type. If no potential ambiguity exists 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 are supplied to the appropriate constructor
when the bean 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>
2009-07-01 23:24:04 +08:00
<para>No potential ambiguity exists, assuming that
<classname>Bar</classname> and <classname>Baz</classname> classes
are not related by inheritance. Thus the following configuration
works fine, and you do not need to specify the constructor argument
2009-07-16 11:17:53 +08:00
indexes and/or types explicitly in the
<literal>&lt;constructor-arg/&gt;</literal> element.</para>
<programlisting language="xml">&lt;beans&gt;
2009-07-16 11:17:53 +08:00
&lt;bean id="foo" class="x.y.Foo"&gt;
&lt;constructor-arg ref="bar"/&gt;
&lt;constructor-arg ref="baz"/&gt;
&lt;/bean&gt;
2009-07-16 11:17:53 +08:00
&lt;bean id="bar" class="x.y.Bar"/&gt;
&lt;bean id="baz class="x.y.Baz"/&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">
2009-07-01 23:24:04 +08:00
<title>Constructor argument type matching</title>
2009-07-16 11:17:53 +08:00
<para>In the preceding scenario, the container
<emphasis>can</emphasis> use type matching with simple types if
you explicitly specify 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">
2009-07-01 23:24:04 +08:00
<title>Constructor argument index</title>
<para>Use the <literal>index</literal> attribute to specify
explicitly the index of constructor arguments. 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>
2009-07-01 23:24:04 +08:00
<para>In addition to resolving the ambiguity of multiple simple
values, specifying an index resolves ambiguity where a constructor
has two arguments of the same type. Note that the <emphasis>index
is 0 based</emphasis>.</para>
</section>
</section>
</section>
<section id="beans-setter-injection">
2009-07-01 23:24:04 +08:00
<title>Setter-based dependency injection</title>
2009-07-16 11:17:53 +08:00
<para><emphasis>Setter-based</emphasis> DI is accomplished by the
container 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>The <interfacename>ApplicationContext</interfacename> supports
constructor- and setter-based DI for the beans it manages. It also
supports setter-based DI after some dependencies are already injected
through the constructor approach.</para>
2009-07-01 23:24:04 +08:00
<para>The following example shows a class that can only be
dependency-injected using pure setter injection. This class is
2009-07-16 11:17:53 +08:00
conventional Java. It is a POJO that has no dependencies on container
specific interfaces, base classes or annotations.</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>
2009-07-01 23:24:04 +08:00
<title>Constructor-based or setter-based DI?</title>
2009-07-16 11:17:53 +08:00
<para>Since you can mix both, Constructor- and Setter-based DI, it
is a good rule of thumb to use constructor arguments for mandatory
dependencies and setters for optional dependencies. Note that the
use of a <link linkend="beans-required-annotation">@Required</link>
annotation on a setter can be used to make setters required
dependencies.</para>
2009-07-01 23:24:04 +08:00
<para>The Spring team generally advocates setter injection, because
large numbers of constructor arguments can get unwieldy, especially
when properties are optional. Setter methods also make objects of
that class amenable to reconfiguration or re-injection later.
Management through <link linkend="jmx">JMX MBeans</link> is a
compelling use case.</para>
<para>Some purists favor constructor-based injection. Supplying all
object dependencies means that the object is always returned to
client (calling) code in a totally initialized state. The
disadvantage is that the object becomes less amenable to
reconfiguration and re-injection.</para>
<para>Use the DI that 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 is made for you. A legacy class may not
expose any setter methods, and so constructor injection is the only
available DI.</para>
</sidebar>
2009-07-16 11:17:53 +08:00
</section>
2009-07-16 11:17:53 +08:00
<section>
<title>Dependency resolution process</title>
2009-07-01 23:24:04 +08:00
2009-07-16 11:17:53 +08:00
<para>The container performs bean dependency resolution as
follows:</para>
<orderedlist>
<listitem>
2009-07-16 11:17:53 +08:00
<para>The <interfacename>ApplicationContext</interfacename> is
created an initialized with configuration metadata that describes
all the beans. Configuration metadata can be specified via XML,
Java code or annotations.</para>
</listitem>
<listitem>
2009-07-16 11:17:53 +08:00
<para>For each bean, its dependencies are expressed in the form of
properties, constructor arguments, or arguments to the
2009-07-01 23:24:04 +08:00
static-factory method if you are using that instead of a normal
constructor. These dependencies are provided to the bean,
<emphasis>when the bean is actually created</emphasis>.</para>
</listitem>
<listitem>
2009-07-16 11:17:53 +08:00
<para>Each property or constructor argument an actual definition
of the value to set, or a reference to another bean in the
container.</para>
</listitem>
<listitem>
2009-07-16 11:17:53 +08:00
<para>Each property or constructor argument which is a value is
converted from its specified format 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>,
2009-07-01 23:24:04 +08:00
<literal>String</literal>, <literal>boolean</literal>, etc.</para>
</listitem>
</orderedlist>
<para>The Spring container validates the configuration of each bean as
2009-07-01 23:24:04 +08:00
the container is created, including the validation of whether bean
reference properties refer to valid beans. However, the bean
properties themselves are not set until the bean <emphasis>is actually
created</emphasis>. Beans that are singleton-scoped and set to be
2009-07-16 11:17:53 +08:00
pre-instantiated (the default) are created when the container is
created. Scopes are defined in the section <xref
linkend="beans-factory-scopes" /> Otherwise, the bean is created only
when it is requested. Creation of a bean potentially causes a graph of
2009-07-01 23:24:04 +08:00
beans to be created, as the bean's dependencies and its dependencies'
dependencies (and so on) are created and assigned.</para>
<sidebar>
<title>Circular dependencies</title>
2009-07-01 23:24:04 +08:00
<para>If you use predominantly constructor injection, it is possible
to create an unresolvable circular dependency scenario.</para>
2009-07-01 23:24:04 +08:00
<para>For example: Class A requires an instance of class B through
constructor injection, and class B requires an instance of class A
2009-07-01 23:24:04 +08:00
through constructor injection. If you configure beans for classes A
and B to be injected into each other, the Spring IoC container
2009-07-16 11:17:53 +08:00
detects this circular reference at runtime, and throws a
<classname>BeanCurrentlyInCreationException</classname>.</para>
2009-07-01 23:24:04 +08:00
<para>One possible solution is to edit the source code of some
classes to be configured by setters rather than constructors.
Alternatively, avoid constructor injection and use setter injection
only. In other words, although it is not recommended, you can
configure circular dependencies with setter injection.</para>
<para>Unlike the <emphasis>typical</emphasis> case (with no circular
2009-07-01 23:24:04 +08:00
dependencies), a circular dependency between bean A and bean B
forces one of the beans to be injected into the other prior to being
fully initialized itself (a classic chicken/egg scenario).</para>
</sidebar>
2009-07-01 23:24:04 +08:00
<para>You can generally trust Spring to do the right thing. It detects
configuration problems, such as references to non-existent beans and
circular dependencies, at container load-time. Spring sets properties
and resolves dependencies as late as possible, when the bean is
2009-07-16 11:17:53 +08:00
actually created. This means that a Spring container which has loaded
correctly can later generate an exception when you request an object
if there is a problem creating that object or one of its dependencies.
For example, the bean throws an exception as a result of a missing or
invalid property. This potentially delayed visibility of some
configuration issues is why
2009-07-01 23:24:04 +08:00
<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 discover configuration issues when the
<interfacename>ApplicationContext</interfacename> is created, not
2009-07-01 23:24:04 +08:00
later. You can still override this default behavior so that singleton
beans will lazy-initialize, rather than be pre-instantiated.</para>
<para>If no circular dependencies exist, when one or more
collaborating beans are being injected into a dependent bean, each
collaborating bean is <emphasis>totally</emphasis> configured prior to
being injected into the dependent bean. This means that if bean A has
a dependency on bean B, the Spring IoC container completely configures
bean B prior to invoking the setter method on bean A. In other words,
the bean is instantiated (if not a pre-instantiated singleton), its
dependencies are 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
2009-07-01 23:24:04 +08:00
callback method</link>) are invoked.</para>
</section>
<section id="beans-some-examples">
<title>Examples of dependency injection</title>
2009-07-01 23:24:04 +08:00
<para>The following example uses XML-based configuration metadata for
setter-based DI. A small part of a Spring XML configuration file
specifies 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>
2009-07-01 23:24:04 +08:00
<para>In the preceding example, setters are declared to match against
the properties specified in the XML file. The following example uses
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>
2009-07-01 23:24:04 +08:00
<para>The constructor arguments specified in the bean definition will
be used as arguments to the constructor of the
<classname>ExampleBean</classname>.</para>
2009-07-01 23:24:04 +08:00
<para>Now consider a variant of this example, 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>
2009-07-01 23:24:04 +08:00
<para>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. The type
of the class being returned by the factory method does not have to be
of the same type as the class that 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, you can define bean
properties and constructor arguments as references to other managed
beans (collaborators), or as values defined inline. Spring's XML-based
configuration metadata supports sub-element types within its
2009-07-01 23:24:04 +08:00
<literal>&lt;property/&gt;</literal> and
<literal>&lt;constructor-arg/&gt;</literal> elements for this
purpose.</para>
<section id="beans-value-element">
2009-07-01 23:24:04 +08:00
<title>Straight values (primitives, <literal>Strings</literal>, and so
on)</title>
<para>The <literal>value</literal> attribute of the
<literal>&lt;property/&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" 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 following example uses the <link
linkend="beans-p-namespace">p-namespace</link> for even more succinct
XML configuration.</para>
<programlisting>&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 id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
p:driverClassName="com.mysql.jdbc.Driver"
p:url="jdbc:mysql://localhost:3306/mydb"
p:username="root"
p:password="masterkaoli"/&gt;
&lt;/beans&gt;
</programlisting>
2009-07-16 11:17:53 +08:00
<para>The preceding XML is more succinct; however, typos are
2009-07-01 23:24:04 +08:00
discovered at runtime rather than design time, unless you use an IDE
such as <ulink url="http://www.jetbrains.com/idea/">IntelliJ
IDEA</ulink> or the <ulink
url="http://www.springsource.com/products/sts">SpringSource Tool
Suite</ulink> (STS) that support automatic property completion when
2009-07-01 23:24:04 +08:00
you create bean definitions. Such IDE assistance is highly
recommended.</para>
<para>You can also configure a <classname>java.util.Properties</classname> instance as:</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>
2009-07-01 23:24:04 +08:00
<para>The Spring container converts the text inside the
<literal>&lt;value/&gt;</literal> element into a
<classname>java.util.Properties</classname> instance by 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> (string value - not a
2009-07-16 11:17:53 +08:00
reference)of another bean in the container to a
<literal>&lt;constructor-arg/&gt;</literal> or
2009-07-01 23:24:04 +08:00
<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 first form is preferable to the second, because using the
2009-07-01 23:24:04 +08:00
<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. Typos are only 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
2009-07-01 23:24:04 +08:00
typo and the resulting exception may only be discovered long after
the container is deployed.</para>
<para>Additionally, if the referenced bean is in the same XML unit,
and the bean name is the bean <emphasis>id</emphasis>, you can use
the <literal>local</literal> attribute, which allows the XML parser
itself to validate the bean id 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>A common place (at least in versions earlier than Spring 2.0)
2009-07-01 23:24:04 +08:00
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. Using
&lt;idref/&gt; elements when you specify the interceptor names
prevents you from 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. Here you
set the value of the specified property of a bean to to be a reference to another
bean (a collaborator) managed by the container. The referenced bean is
2009-07-01 23:24:04 +08:00
a dependency of the bean whose property will be set, and it is
initialized on demand as needed before the property is set. (If the collaborator is
2009-07-01 23:24:04 +08:00
a singleton bean, it may be initialized already by the container.) All
references are ultimately a reference to another object. Scoping and validation
depend on whether you specify the id/name of the other object through the
<literal>bean,<literal>local,</literal></literal> or
<literal>parent</literal> attributes.</para>
<para>Specifying the target bean through the <literal>bean</literal>
attribute of the <literal>&lt;ref/&gt;</literal> tag is the most
2009-07-01 23:24:04 +08:00
general form, and allows creation of a reference to any bean in the
same container or parent container, regardless of whether it is in the
same XML file. The value of the <literal>bean</literal> attribute may
be the same as the <literal>id</literal> attribute of the target bean,
or as one of the values in the <literal>name</literal> attribute of
2009-07-01 23:24:04 +08:00
the target bean.</para>
<programlisting language="xml">&lt;ref bean="someBean"/&gt;</programlisting>
<para>Specifying the target bean through 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
2009-07-01 23:24:04 +08:00
issues 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 through the <literal>parent</literal>
attribute creates a reference to a bean that 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 of the current one. You use this
bean reference variant mainly when you have a hierarchy of containers
and you want to wrap an existing bean in a parent container with a
proxy that 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
2009-07-01 23:24:04 +08:00
<literal>&lt;constructor-arg/&gt;</literal> elements defines a
so-called <firstterm>inner bean</firstterm>.</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>An inner bean definition does not require a defined id or name;
the container ignores these values. It also ignores the
<literal>scope</literal> flag. Inner beans are
<emphasis>always</emphasis> anonymous and they are
<emphasis>always</emphasis> scoped as <link
2009-07-01 23:24:04 +08:00
linkend="beans-factory-scopes-prototype">prototypes</link>. It is
<emphasis>not</emphasis> possible to inject inner beans into
collaborating beans other than into the enclosing bean.</para>
</section>
<section id="beans-collection-elements">
<title>Collections</title>
<para>In the <literal>&lt;list/&gt;</literal>,
<literal>&lt;set/&gt;</literal>, <literal>&lt;map/&gt;</literal>, and
<literal>&lt;props/&gt;</literal> elements, you set the properties and
arguments of the Java <interfacename>Collection</interfacename> types
<interfacename>List</interfacename>,
<interfacename>Set</interfacename>,
<interfacename>Map</interfacename>, and
<interfacename>Properties</interfacename>, respectively.</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 key="an entry" value="just some string"/&gt;
&lt;entry key ="a ref" value-ref="myDataSource"/&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>
2009-07-01 23:24:04 +08:00
<para><emphasis>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>
2009-07-01 23:24:04 +08:00
<para>As of Spring 2.0, the container supports the
<emphasis>merging</emphasis> of collections. An application
developer can 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
2009-07-01 23:24:04 +08:00
values from the parent collection. That is, the child collection's
values are the result of merging the elements of the parent and
child collections, with the child's collection elements overriding
values specified in the parent collection.</para>
<para><emphasis>This section on merging discusses the parent-child
bean mechanism. Readers unfamiliar with parent and child bean
definitions may wish to read the <link
linkend="beans-child-bean-definitions">relevant section</link>
before continuing.</emphasis></para>
2009-07-01 23:24:04 +08:00
<para>The following example demonstrates collection merging:</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
2009-07-01 23:24:04 +08:00
<literal>child</literal> bean is resolved and instantiated by the
container, the resulting instance has 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>
2009-07-01 23:24:04 +08:00
<para>The child <classname>Properties</classname> collection's value
set inherits all property elements from the parent
<literal>&lt;props/&gt;</literal>, and 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
2009-07-01 23:24:04 +08:00
type, that is, the notion of an <literal>ordered</literal>
collection of values, is maintained; the parent's values precede all
of the child list's values. In the case of the
<interfacename>Map</interfacename>,
<interfacename>Set</interfacename>, and
2009-07-01 23:24:04 +08:00
<interfacename>Properties</interfacename> collection types, no
ordering exists. Hence no ordering semantics are in effect for the
collection types that underlie the associated
<interfacename>Map</interfacename>,
2009-07-01 23:24:04 +08:00
<interfacename>Set</interfacename>, and
<interfacename>Properties</interfacename> implementation types that
the container uses internally.</para>
2009-07-01 23:24:04 +08:00
</section>
2009-07-01 23:24:04 +08:00
<section>
<title>Limitations of collection merging</title>
<para>You cannot merge different collection types (such as a
<interfacename>Map</interfacename> and a
<interfacename>List</interfacename>), and if you do attempt to do so
2009-07-01 23:24:04 +08:00
an appropriate <classname>Exception</classname> is thrown. The
<literal>merge</literal> attribute must be specified on the lower,
inherited, child definition; specifying the <literal>merge</literal>
attribute on a parent collection definition is redundant and will
not result in the desired merging. The merging feature is available
only in Spring 2.0 and later.</para>
</section>
<section id="beans-collection-elements-strongly-typed">
<title>Strongly-typed collection (Java 5+ only)</title>
2009-07-01 23:24:04 +08:00
<para>In Java 5 and later, you can use 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
2009-07-01 23:24:04 +08:00
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>
2009-07-01 23:24:04 +08:00
instances are 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 prepared for injection, the generics
information about the element type of the strongly-typed
2009-07-01 23:24:04 +08:00
<classname>Map&lt;String, Float&gt;</classname> is available by
reflection. Thus Spring's type conversion infrastructure recognizes
the various value elements as being of type
<classname>Float</classname>, and the string values <literal>9.99,
2.75</literal>, and <literal>3.99</literal> are converted into an
actual <classname>Float</classname> type.</para>
</section>
</section>
<section id="beans-null-element">
2009-07-01 23:24:04 +08:00
<title>Null and empty string values</title>
<para><!--Clarify difference between null value and empty string value?-->Spring
treats empty arguments for properties and the like as empty
<literal>Strings</literal>. The following XML-based configuration
metadata snippet sets the email property to the empty
2009-07-01 23:24:04 +08:00
<classname>String</classname> value ("")</para>
<programlisting language="xml">&lt;bean class="ExampleBean"&gt;
&lt;property name="email" value=""/&gt;
&lt;/bean&gt;</programlisting>
2009-07-01 23:24:04 +08:00
<para>The preceding example is equivalent to the following Java code:
<methodname>exampleBean.setEmail("")</methodname>. The
<literal>&lt;null/&gt;</literal> element handles
<literal>null</literal> values. 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>
2009-07-01 23:24:04 +08:00
<section id="beans-p-namespace">
2009-07-16 11:17:53 +08:00
<title>XML shortcut with the p-namespace</title>
2009-07-01 23:24:04 +08:00
<para>The p-namespace enables you to use the <literal>bean</literal>
element's attributes, instead of nested
<literal>&lt;property/&gt;</literal> elements, to describe your
property values and/or collaborating beans.</para>
<para>Spring 2.0 and later supports extensible configuration formats
<link linkend="xsd-config">with namespaces</link>, which are based on
an XML Schema definition. The <literal>beans</literal> configuration
format discussed in this chapter is defined in an XML Schema document.
However, the p-namespace is not defined in an XSD file and exists only
in the core of Spring.</para>
<para>The following example shows two XML snippets that resolve to the
same result: The first uses standard XML format and the second uses
the p-namespace.</para>
2009-07-01 23:24:04 +08:00
<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>The example shows an attribute in the p-namespace called email
in the bean definition. This tells Spring to include a property
declaration. As previously mentioned, the p-namespace not have a
schema definition, so you can set the name of the attribute to the
property name.</para>
2009-07-01 23:24:04 +08:00
<para>This next example includes two more bean definitions that both
have a reference to another bean:</para>
2009-07-01 23:24:04 +08:00
<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 includes not only a property value
using the p-namespace, but also uses a special format to declare
2009-07-01 23:24:04 +08:00
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
2009-07-01 23:24:04 +08:00
not a straight value but rather a reference to another bean.</para>
<note>
<para>The p-namespace is not as flexible as the standard XML format.
For example, the format for declaring property references clashes
with properties that end in <literal>Ref</literal>, whereas the
standard XML format does not. We recommend that you choose your
approach carefully and communicate this to your team members, to
avoid producing XML documents that use all three approaches at the
same time.<!--Clarify ref to all three approaches.I see two, XML and namespace.--></para>
2009-07-01 23:24:04 +08:00
</note>
</section>
<section id="beans-compound-property-names">
<title>Compound property names</title>
<para>You can use compound or nested property names when you set 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> after the bean is constructed, or a
<exceptionname>NullPointerException</exceptionname> is thrown.</para>
</section>
</section>
<section id="beans-factory-dependson">
<title>Using <literal>depends-on</literal></title>
<para>If a bean is a dependency of another that usually means that one
bean is set as a property of another. Typically you accomplish this with
the <link linkend="beans-ref-element"><literal>&lt;ref/&gt;</literal>
element</link> in XML-based configuration metadata. However, sometimes
dependencies between beans are less direct; for example, a static
initializer in a class needs to be triggered, such as database driver
registration. The <literal>depends-on</literal> attribute can explicitly
force one or more beans to be initialized before the bean using this
element is initialized. The following example uses 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>To express a dependency on multiple beans, supply a list of bean
names as the value of the <literal>depends-on</literal> attribute, with
commas, whitespace and semicolons, used as valid delimiters:</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 in the bean
definition can specify both an initialization time dependency
and, in the case of <link
linkend="beans-factory-scopes-singleton">singleton</link> beans only,
a corresponding destroy time dependency. Dependent beans that define
a <literal>depends-on</literal> relationship with a given bean are
destroyed first, prior to the given bean itself being destroyed. Thus
<literal>depends-on</literal> can also control shutdown order.</para>
</note>
</section>
<section id="beans-factory-lazy-init">
<title>Lazy-initialized beans<!--Changed to lazy-initialized from lazily instantiated because attribute is lazy-init, and there was a lot of inconsistency. --></title>
<para>By default,<interfacename> ApplicationContext</interfacename>
implementations eagerly create and configure all <link
linkend="beans-factory-scopes-singleton">singleton</link> beans as part
of the initialization process. Generally, this pre-instantiation is
desirable, because errors in the configuration or surrounding
environment are discovered immediately, as opposed to hours or even days
later. When this behavior is <emphasis>not</emphasis> desirable, you can
prevent pre-instantiation of a singleton bean by marking the bean
definition as lazy-initialized. A lazy-initialized bean tells the IoC
container to create a bean instance when it is first requested, rather
than at startup.<!--Above, clarify what you mean by eagerly. Note, I've trimmed this section for conciseness, but info is still here.--></para>
<para>In XML, this behavior 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 preceding configuration is consumed by an
<interfacename>ApplicationContext</interfacename>, the bean named
<literal>lazy</literal> is not eagerly pre-instantiated when the
<interfacename>ApplicationContext</interfacename> is starting up,
whereas the <literal>not.lazy</literal> bean is eagerly
pre-instantiated.</para>
<para>However, when a lazy-initialized bean is a dependency of a
singleton bean that is <emphasis>not</emphasis> lazy-initialized, the
<interfacename>ApplicationContext</interfacename> creates the
lazy-initialized bean at startup, because it must satisfy the
singleton's dependencies. The lazy-initialized bean is injected into a
singleton bean elsewhere that is not lazy-initialized.</para>
<para>You can also 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>
<!--I've moved around info and done a lot of editing/reformatting in this section, but nothing is missing.-->
<para>The Spring container can <emphasis>autowire</emphasis>
relationships between collaborating beans. You can allow Spring to
resolve collaborators (other beans) automatically for your bean by
inspecting the contents of the
<interfacename>ApplicationContext</interfacename>. Autowiring has the
following advantages:</para>
<para><itemizedlist>
<listitem>
<para>Autowiring can significantly reduce the need to specify
properties or constructor arguments. (Other mechanisms such as 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 update a configuration as your objects
evolve. For example, if you need to add a dependency to a class,
that dependency can be satisfied automatically your needing to
modify the configuration. Thus autowiring can be especially useful
during development, without negating the option of switching to
explicit wiring when the code base becomes more stable.</para>
</listitem>
</itemizedlist><footnote>
<para>See <xref linkend="beans-factory-collaborators" /></para>
</footnote> When using XML-based configuration metadata, you specify
autowire mode for a bean definition with the <literal>autowire</literal>
attribute of the <literal>&lt;bean/&gt;</literal> element. The
autowiring functionality has five modes. You specify autowiring
<emphasis>per</emphasis> bean and thus can choose which ones to
autowire.</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>(Default) No autowiring. Bean references must be
defined via a <literal>ref</literal> element. Changing the
default setting is not recommended for larger deployments,
because specifying collaborators explicitly gives greater
control and clarity. To some extent, it documents the structure
of a system.</para></entry>
</row>
<row>
<entry>byName</entry>
<entry><para>Autowiring by property name. Spring looks for a
bean with the same name as the property that needs to be
autowired. For example, if a bean definition is set to autowire
by name, and it contains a <emphasis>master</emphasis> property
(that is, it has a <emphasis>setMaster(..)</emphasis> method),
Spring looks for a bean definition named
<literal>master</literal>, and uses it to set the
property.</para></entry>
</row>
<row>
<entry>byType</entry>
<entry><para>Allows a property to be autowired if exactly one
bean of the property type exists in the container. If more than
one exists, a fatal exception is thrown, which 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>Analogous to <emphasis>byType</emphasis>, but
applies to constructor arguments. If there is not 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 is applied.</para></entry>
</row>
</tbody>
</tgroup>
</table>
<para>With <emphasis>byType</emphasis> or
<emphasis>constructor</emphasis> autowiring mode, you can wire arrays
and typed-collections. In such cases <emphasis>all</emphasis> autowire
candidates within the container that match the expected type are
provided to satisfy the dependency. You can autowire strongly-typed Maps
if the expected key type is <classname>String</classname>. An autowired
Maps values will consist of all bean instances that match the expected
type, and the Maps keys will contain the corresponding bean
names.</para>
<para>You can combine autowire behavior with dependency checking, which
is performed after autowiring completes.</para>
<section id="beans-autowired-exceptions">
<title>Limitations and disadvantages of autowiring</title>
<para>Autowiring works best when it is used consistently across a
project. If autowiring is not used in general, it might be confusing
to developers to use it to wire only one or two bean
definitions.</para>
<para>Consider the limitations and disadvantages of autowiring:</para>
<itemizedlist>
<listitem>
<para>Explicit dependencies in <literal>property</literal> and
<literal>constructor-arg</literal> settings always override
autowiring. You cannot autowire so-called
<emphasis>simple</emphasis> properties such as primitives,
<classname>Strings</classname>, and <classname>Classes</classname>
(and arrays of such simple properties). This limitation is
by-design.</para>
</listitem>
</itemizedlist>
<itemizedlist>
<listitem>
<para>Autowiring is less exact than explicit wiring. Although, as
noted in the above table, Spring is careful to avoid guessing in
case of ambiguity that 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>
<itemizedlist>
<listitem>
<para>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 is not arbitrarily resolved. If no
unique bean definition is available, an exception is
thrown.</para>
</listitem>
</itemizedlist>
<para>In the latter scenario, you have several options:</para>
<itemizedlist>
<listitem>
<para>Abandon autowiring in favor of explicit wiring.</para>
</listitem>
<listitem>
<para>Avoid autowiring for a bean definition by setting its
<literal>autowire-candidate</literal> attributes to
<literal>false</literal> as described in the next section.</para>
</listitem>
<listitem>
<para>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>.</para>
</listitem>
<listitem>
<para>If you are using Java 5 or later, implement the more
fine-grained control available with annotation-based
configuration, as described in <xref
linkend="beans-annotation-config" />.</para>
</listitem>
</itemizedlist>
</section>
<section id="beans-factory-autowire-candidate">
<title>Excluding a bean from autowiring</title>
<para>On a per-bean basis, you can exclude a bean from autowiring. In
Spring's XML format, set the <literal>autowire-candidate</literal>
attribute of the <literal>&lt;bean/&gt;</literal> element to
<literal>false</literal>; the container makes that specific bean
definition unavailable to the autowiring infrastructure.</para>
<para>You can also 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. An
explicit value of <literal>true</literal> or <literal>false</literal>
for a bean definitions <literal>autowire-candidate</literal> attribute
always takes precedence, and for such beans, the pattern matching
rules do not apply.</para>
<para>These techniques are useful for beans that you never want to be
injected into other beans by autowiring. It does not mean that an
excluded bean cannot itself be configured using autowiring. Rather,
the bean itself is not a candidate for autowiring other beans.</para>
<!--Last paragraph unclear to me. Is my edit ok? Revise as necessary.-->
</section>
</section>
<section id="beans-factory-dependencies">
<title>Checking for dependencies</title>
<para>The Spring IoC container can check for unresolved dependencies of
a bean deployed into the container. When enabling checking for unresolved dependencies
all JavaBean properties of the bean must have explicit values set for them in the bean
definition or have their values set via autowiring.<!--Please revise preceding sentence, wording doesn't track.--></para>
<para>This feature is useful when you want to ensure that all properties
(or all properties of a certain type) are set on a bean. A bean class
often has default values for many properties, or some properties do not
apply to all usage scenarios, so this feature is of limited use. You can
enable dependency checking per bean, just as with the autowiring
functionality. The default is to <emphasis>not</emphasis> check
dependencies. In XML-based configuration metadata, you specify
dependency checking via the
<literal>dependency-check</literal> attribute in a bean definition,
which can 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>(Default) No dependency checking. Properties of the
bean that have no value specified for them are not
set.</para></entry>
</row>
<row>
<entry>simple</entry>
<entry><para>Dependency checking for primitive types and
collections (everything except collaborators).</para></entry>
</row>
<row>
<entry>object</entry>
<entry><para>Dependency checking for collaborators
only.</para></entry>
</row>
<row>
<entry>all</entry>
<entry><para>Dependency checking for collaborators, primitive
types, and collections.</para></entry>
</row>
</tbody>
</tgroup>
</table>
<para>If you use Java 5 and thus have access to source-level
annotations, you may find <xref
linkend="metadata-annotations-required" /> to be of interest.</para>
</section>
<section id="beans-factory-method-injection">
<title>Method injection</title>
<para>In most application scenarios, most beans in the container are
<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,
you typically handle the dependency by defining one bean as a property
of the other. A problem arises when the bean lifecycles are different.
Suppose singleton bean A needs to use non-singleton (prototype) bean B,
perhaps on each method invocation on A. The container only creates the
singleton bean A once, and thus only gets one opportunity to set the
properties. The container cannot provide bean A with a new instance of
bean B every time one is needed.</para>
<para>A solution is to forego some inversion of control. You can <link
linkend="beans-factory-aware-beanfactoryaware">make bean A aware of the
container</link> by implementing the
<interfacename>ApplicationContextFactoryAware</interfacename> interface,
and by <link linkend="beans-factory-client">making a getBean("B")
call to the container</link> ask for (a typically new) bean B instance every
time bean A needs it. The following is a contrived example of this
approach:<!--Why give a contrived example, why not a realistic one?--></para>
<!--First link goes to ApplicationContextAware, not ApplicationContextFactoryAware. Second link is to ApplicationContext.-->
<programlisting language="java"><lineannotation>// a class that uses a stateful Command-style class to perform some processing</lineannotation>
package fiona.apple;
<lineannotation>// Spring-API imports</lineannotation>
import org.springframework.beans.BeansException;
import org.springframework.context.Applicationcontext;
import org.springframework.context.ApplicationContextAware;
public class CommandManager implements ApplicationContextAware {
private ApplicationContext applicationContext;
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 this.applicationContext.getBean("command", Command.class); <lineannotation>// notice the Spring API dependency</lineannotation>
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}</programlisting>
<para>The preceding is not desirable, because the business code is 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.<!--Why give an example that is not desirable? Unclear whether this is an illustration of true method injection.--></para>
<sidebar>
<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>
<section id="beans-factory-lookup-method-injection">
<title>Lookup method injection</title>
<!--Deleted a box here that doesn't seem to have much info; I moved the blog entry link above. -->
<para>Lookup method injection is the ability of the container to
override methods on <emphasis>container managed beans</emphasis>, to
return the lookup result for another named bean in the container. The
lookup typically involves a prototype bean as in the scenario
described in the preceding section. The Spring Framework implements
this method injection by using bytecode generation from the CGLIB
library to generate dynamically a subclass that overrides the method.
<!--Note was plain text; I made it a note and moved it up.--></para>
<note>
<para>For this dynamic subclassing to work, you must have the CGLIB
jar(s) in your classpath. The class that the Spring container will
subclass cannot be <literal>final</literal>, and the method to be
overridden cannot be <literal>final</literal> either. Also, testing
a class that has an <literal>abstract</literal> method requires you
to subclass the class yourself and to supply a stub implementation
of the <literal>abstract</literal> method. Finally, objects that
have been the target of method injection cannot be
serialized.</para>
</note>
<para>Looking at the <classname>CommandManager</classname> class in
the previous code snippet, you see that the Spring container will
dynamically override the implementation of the
<methodname>createCommand()</methodname> method. Your
<classname>CommandManager</classname> class will not have any Spring
dependencies, as can be seen in the reworked example:</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 to be
injected requires 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 implements the method. Otherwise, the
dynamically-generated subclass overrides the concrete method defined
in the original class. For 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> calls
its own method <methodname>createCommand()</methodname> whenever it
needs a new instance of the <emphasis>command</emphasis> bean. You
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 is returned each
time.</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 used in ServiceLocatorFactoryBean is
similar to that of another utility class,
<classname>ObjectFactoryCreatingFactoryBean</classname>, but it
allows you to specify your own lookup interface as opposed to a
Spring-specific lookup interface. Consult the JavaDocs for these
classes as well as this <ulink
url="http://blog.arendsen.net/index.php/2006/10/05/on-the-servicelocatorfactorybean-dlas-and-the-sustainability-of-code-and-design/">blog
entry</ulink> for additional information
ServiceLocatorFactoryBean.</para>
</tip>
</section>
<section id="beans-factory-arbitrary-method-replacement">
<title>Arbitrary method replacement</title>
<para>A less 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 until the functionality is actually needed.<!--Delete this section? See preceding sentence.--></para>
<para>With XML-based configuration metadata, you can use the
<literal>replaced-method</literal> element 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>You can use one or more contained
<literal>&lt;arg-type/&gt;</literal> elements within the
<literal>&lt;replaced-method/&gt;</literal> element to indicate the
method signature of the method being overridden. The signature for the
arguments is necessary only if the method is overloaded and multiple
variants exist within the class. For convenience, the type string for
an argument may be a substring of the fully qualified type name. For
example, the following all match
<classname>java.lang.String</classname>:</para>
<programlisting language="java"> java.lang.String
String
Str</programlisting>
<para>Because 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 only 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-session">session</link>
</para></entry>
<entry><para>Scopes a single bean definition to the lifecycle of
an 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
2009-06-10 07:39:37 +08:00
<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>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 an 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 (for example) an 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 an 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;!-- an 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 an 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
an 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>ApplicationContextAware</interfacename></title>
<para>A class which implements the
<interfacename>org.springframework.contxt.ApplicationContextAware</interfacename>
interface is provided with a reference to the
<interfacename>ApplicationContext</interfacename> that created it,
when it is created by that
<interfacename>ApplicationContext</interfacename>.</para>
<programlisting language="java">public interface ApplicationContextAware {
void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}</programlisting>
<para>This allows beans to manipulate the
<interfacename>ApplicationContext</interfacename> that created them
programmatically, through the
<interfacename>ApplicationContext</interfacename> interface, or by
casting the reference to a known subclass of this which exposes
additional functionality, for example
<classname>ConfigurableApplicationContext</classname>. One use would
be the 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. Other methods on the ApplicationContext provide access to
file resources, publishing application events, or accessing a
MessageSource. These additional features are described in the section
<xref linkend="context-introduction" /></para>
<para>As of Spring 2.5, you can rely upon autowiring of the
<interfacename>ApplicationContext</interfacename> as yet another
alternative to implementing the
<interfacename>ApplicationContextAware</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>ApplicationContext</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>ApplicationFactory</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 the and is deployed in a
<interfacename>ApplicationContext</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>ApplicationContext</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>ClassPathXmlApplicationContext</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> 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>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 note that 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.</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 automatically when
declared inside 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>A custom
<interfacename>BeanFactoryPostProcessor</interfacename> can also be used
to register custom property editors, for example.</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 bean 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" value="classpath:com/foo/jdbc.properties"/&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>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
programmatically, 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.</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-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><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>
<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>
<section id="beans-annotation-config">
<title>Annotation-based container 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
2009-04-30 05:14:01 +08:00
<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>ApplicationContext</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>
2009-05-02 03:48:08 +08:00
<section id="beans-classpath-scanning">
<title>Classpath scanning and managed components</title>
2009-05-02 03:48:08 +08:00
<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
2009-05-02 04:14:23 +08:00
<interfacename>@Configuration</interfacename>, <interfacename>@Bean,
@Import</interfacename> and <interfacename>@DependsOn</interfacename>
annotations for how to use these new features.</para>
2009-05-02 03:48:08 +08:00
</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
2009-06-16 10:37:19 +08:00
linkend="orm-exception-translation" />.</para>
2009-05-02 03:48:08 +08:00
<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
2009-05-02 03:48:08 +08:00
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Autowired
public SimpleMovieLister(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
}</programlisting>
2009-05-02 03:48:08 +08:00
<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"
2009-05-02 03:48:08 +08:00
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;
2009-05-02 03:48:08 +08:00
&lt;context:component-scan base-package="org.example"/&gt;
2009-05-02 03:48:08 +08:00
&lt;/beans&gt;</programlisting>
2009-05-02 03:48:08 +08:00
<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;
2009-05-02 03:48:08 +08:00
&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;
2009-05-02 03:48:08 +08:00
&lt;/beans&gt;</programlisting>
2009-05-02 03:48:08 +08:00
<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>
2009-04-30 05:14:01 +08:00
<section id="beans-factorybeans-annotations">
<title>Defining bean metadata within components</title>
2009-05-02 03:48:08 +08:00
<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="beans-javaconfig">
<title>Java-based container configuration</title>
<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.
2009-04-30 05:14:01 +08:00
The simplest possible <interfacename>@Configuration</interfacename>
class would read as follows: <programlisting language="java">@Configuration
2009-04-30 05:14:01 +08:00
public class AppConfig {
} </programlisting></para>
2009-04-30 05:14:01 +08:00
2009-05-02 03:48:08 +08:00
<para>An application may make use of one
2009-04-30 05:14:01 +08:00
<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
2009-04-30 12:35:30 +08:00
annotation supports some of the attributes offered by
2009-04-30 05:14:01 +08:00
<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>,
2009-04-30 12:35:30 +08:00
<code><link linkend="beans-factory-autowire">autowiring</link></code>
and <code>name</code>.</para>
2009-04-30 05:14:01 +08:00
<para>You can use the <interfacename>@Bean</interfacename> annotation in
a Configuration-class or in a Component-class.</para>
2009-05-02 03:48:08 +08:00
2009-04-30 05:14:01 +08:00
<section id="beans-javaconfig-declaring-a-bean">
<title>Declaring a bean</title>
<para>To declare a bean, simply annotate a method with the
2009-05-02 03:48:08 +08:00
<interfacename>@Bean</interfacename> annotation. Such a method will be
used to register a bean definition within a
<code>ApplicationContext</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
2009-04-30 05:14:01 +08:00
public class AppConfig {
2009-05-02 03:48:08 +08:00
2009-04-30 05:14:01 +08:00
@Bean
public TransferService transferService() {
return new TransferServiceImpl();
}
2009-05-02 03:48:08 +08:00
}</programlisting></para>
2009-04-30 05:14:01 +08:00
<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>
2009-04-30 05:14:01 +08:00
<para>Both will result in a bean named <code>transferService</code>
being available in the <code>ApplicationContext</code>, bound to an
object instance of type <code>TransferServiceImpl</code>:
<programlisting>
transferService -&gt; com.acme.TransferServiceImpl
</programlisting></para>
2009-04-30 05:14:01 +08:00
</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
2009-04-30 05:14:01 +08:00
public class AppConfig {
2009-05-02 03:48:08 +08:00
2009-04-30 05:14:01 +08:00
@Bean
public Foo foo() {
return new Foo(bar());
}
@Bean
public Bar bar() {
return new Bar();
}
2009-05-02 03:48:08 +08:00
} </programlisting></para>
2009-04-30 05:14:01 +08:00
<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 {
2009-04-30 05:14:01 +08:00
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>
2009-04-30 05:14:01 +08:00
<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
2009-04-30 05:14:01 +08:00
public class AppConfig {
@Bean
public Foo foo() {
Foo foo = new Foo();
foo.init();
return foo;
}
// ...
} </programlisting></para>
2009-04-30 05:14:01 +08:00
<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>
2009-04-30 05:14:01 +08:00
<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 default scope is <literal>"singleton"</literal>, but this
can be overridden by using the <interfacename>@Scope</interfacename>
annotation: <programlisting language="java">@Configuration
2009-04-30 05:14:01 +08:00
public class MyConfiguration {
@Bean
<emphasis role="bold">@Scope("prototype")</emphasis>
2009-04-30 05:14:01 +08:00
public Encryptor encryptor() {
// ...
}
}</programlisting></para>
2009-04-30 05:14:01 +08:00
</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 XML reference documentation scoped
2009-04-30 05:14:01 +08:00
proxy example (see link above) to our
<interfacename>@Bean</interfacename> using Java, it would look like
the following: <programlisting language="java">// an HTTP Session-scoped bean exposed as a proxy
2009-04-30 05:14:01 +08:00
@Bean
<emphasis role="bold">@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)</emphasis>
2009-04-30 05:14:01 +08:00
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>
2009-04-30 05:14:01 +08:00
</section>
<section id="beans-javaconfig-method-injection">
<title>Lookup method injection</title>
2009-05-02 04:14:23 +08:00
<para>As noted earlier, <link
2009-04-30 05:14:01 +08:00
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
2009-05-02 03:48:08 +08:00
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 {
2009-04-30 05:14:01 +08:00
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>
2009-04-30 05:14:01 +08:00
<para>Using Java-configuration support we can easily create a
2009-05-02 04:14:23 +08:00
subclass of <code>CommandManager</code> where the abstract
<code>createCommand()</code> method is overridden in such a way that
it 'looks up' a brand new (prototype) command object:
<programlisting language="java">@Bean
@Scope("prototype")
2009-04-30 05:14:01 +08:00
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>
2009-04-30 05:14:01 +08:00
</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
2009-04-30 05:14:01 +08:00
public class AppConfig {
@Bean(name = "bar")
public Foo foo() {
return new Foo();
}
} </programlisting></para>
2009-04-30 05:14:01 +08:00
</section>
</section>
</section>
2009-04-30 05:14:01 +08:00
<section id="beans-beanfactory">
<title>The BeanFactory</title>
<para>The <classname>BeanFactory</classname> provides the underlying basis
for Spring's IoC functionality but it is only used directly in integration
with other third-party frameworks and is now largely historical in nature
for most users of Spring. The <classname>BeanFactory</classname> and
related interfaces, such as <classname>BeanFactoryAware</classname>,
<classname>InitializingBean</classname>,
<classname>DisposableBean</classname>, are still present in Spring for the
purposes of backward compatibility with the large number of third-party
frameworks that integrate with Spring. Often third-party components that
can not use more modern equivalents such as @PostConstruct or @PreDestroy
in order to remain compatible with JDK 1.4 or avoid a dependency on
JSR-250.</para>
<para>This section provides some additional background into the
differences between the BeanFactory and ApplicationContext and how one
might access the IoC container directly via a 'classic' singleton
lookup.</para>
<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
implementations.</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>
<para>To explicitly register a bean post-processor when using a
<interfacename>BeanFactory</interfacename> implementation you will need
to write 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>
<para>To explicitly register a
<classname>BeanFactoryPostProcessor</classname> when using a
<interfacename>BeanFactory</interfacename> implementation you will need
to write code like 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>In both cases, the 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> and
<classname>BeanPostProcessors</classname>, which are the mechanisms by
which important functionality such as property placeholder replacement
and AOP are implemented.</para>
</section>
2009-07-16 11:17:53 +08:00
<section id="beans-servicelocator">
<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>Looking up the application context in a service locator style is
sometimes the only option you have to access shared Spring managed
components, such as in an EJB 2.1 environment, or you want to share a
single ApplicationContext as a parent to WebApplicationContexts across
war files. In this case you should look into using the utility class
<ulink
url="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/context/access/ContextSingletonBeanFactoryLocator.html"><classname>ContextSingletonBeanFactoryLocator</classname></ulink>
locator that is described in this <ulink
url="http://blog.springsource.com/2007/06/11/using-a-shared-parent-application-context-in-a-multi-war-spring-application/">SpringSource
team blog entry</ulink>.</para>
</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>