All <section/> elements in beans.xml >=~ 500 lines have been broken out into separate documents with DOCTYPE 'section'. This refactoring makes working with these files much easier in wysiwyg editors (namely oXygen Author). For consistency, this same refactoring should be applied to all other chapters much larger than 1500 lines, such as aop.xml (3861), mvc.xml (3466), jdbc.xml (3042), and so on. beans.xml and the new section files have also been formatted for consistency and to avoid whitespace diffs as much as possible into the future.
1176 lines
57 KiB
XML
1176 lines
57 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
|
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
|
<chapter id="beans">
|
|
<title>The IoC container</title>
|
|
|
|
<section id="beans-introduction">
|
|
<title>Introduction to the Spring IoC container and beans</title>
|
|
|
|
<para>This chapter covers the Spring Framework implementation of the
|
|
Inversion of Control (IoC) <footnote>
|
|
<para>See <xref linkend="background-ioc"/></para>
|
|
</footnote>principle. IoC is also known as <emphasis>dependency
|
|
injection</emphasis> (DI). It 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 bean. This process is fundamentally the
|
|
inverse, hence the name <emphasis>Inversion of Control</emphasis> (IoC),
|
|
of the bean itself controlling the instantiation or location of its
|
|
dependencies by using direct construction of classes, or a mechanism such
|
|
as the <emphasis>Service Locator</emphasis> pattern.</para>
|
|
|
|
<!--I copied and pasted preceding from "Injecting Dependencies" to give background on IoC, since that's what chapter is about.
|
|
The footnote should x-ref to first section in that chapter but I can't find the file. The current xref doesn't work.-->
|
|
|
|
<para>The <literal>org.springframework.beans</literal> and
|
|
<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/3.0.x/javadoc-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/3.0.x/javadoc-api/org/springframework/context/ApplicationContext.html"
|
|
>ApplicationContext</ulink></literal> is a sub-interface of
|
|
<interfacename>BeanFactory.</interfacename> It adds easier integration
|
|
with Spring's AOP features; message resource handling (for use in
|
|
internationalization), event publication; and application-layer specific
|
|
contexts such as the <interfacename>WebApplicationContext</interfacename>
|
|
for use in web applications.</para>
|
|
|
|
<para>In short, the <interfacename>BeanFactory</interfacename> provides the
|
|
configuration framework and basic functionality, and the
|
|
<interfacename>ApplicationContext</interfacename> adds more
|
|
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>
|
|
|
|
<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> among them, are
|
|
reflected in the <firstterm>configuration metadata</firstterm> used by a
|
|
container.</para>
|
|
</section>
|
|
|
|
<section id="beans-basics">
|
|
<title>Container overview</title>
|
|
|
|
<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 instance of <ulink
|
|
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>.
|
|
<!-- MLP: Beverly to review --> While XML has been the traditional format
|
|
for defining configuration metadata you can 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 these additional
|
|
metadata formats.</para>
|
|
|
|
<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 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>
|
|
|
|
<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>
|
|
<imageobject>
|
|
<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 objects in your
|
|
application.</para>
|
|
|
|
<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>
|
|
|
|
<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>
|
|
|
|
<para>For information about using other forms of metadata with the Spring
|
|
container, see:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><link linkend="beans-annotation-config">Annotation-based
|
|
configuration</link>: Spring 2.5 introduced support for
|
|
annotation-based configuration metadata.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para><link linkend="beans-java">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>
|
|
|
|
<para>Spring configuration consists of at least one and typically more
|
|
than one bean definition that the container must manage. XML-based
|
|
configuration metadata shows these beans configured as
|
|
<literal><bean/></literal> elements inside a top-level
|
|
<literal><beans/></literal> element.</para>
|
|
|
|
<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"><?xml version="1.0" encoding="UTF-8"?>
|
|
<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">
|
|
|
|
<bean id="..." class="...">
|
|
<!-- collaborators and configuration for this bean go here -->
|
|
</bean>
|
|
|
|
<bean id="..." class="...">
|
|
<!-- collaborators and configuration for this bean go here -->
|
|
</bean>
|
|
|
|
<!-- more bean definitions go here -->
|
|
|
|
</beans></programlisting>
|
|
|
|
<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>
|
|
|
|
<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>
|
|
|
|
<programlisting language="java">ApplicationContext context =
|
|
new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"});</programlisting>
|
|
|
|
<note>
|
|
<para>After you learn about Spring's IoC container, you may want to know
|
|
more about Spring's <interfacename>Resource</interfacename>
|
|
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,
|
|
<classname>Resource</classname> paths are used to construct
|
|
applications contexts as described in <xref
|
|
linkend="resources-app-ctx"/>.</para>
|
|
</note>
|
|
|
|
<para>The following example shows the service layer objects
|
|
<literal>(services.xml)</literal> configuration file:</para>
|
|
|
|
<programlisting language="xml"><?xml version="1.0" encoding="UTF-8"?>
|
|
<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">
|
|
|
|
<!-- services -->
|
|
|
|
<bean id="petStore"
|
|
class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl">
|
|
<property name="accountDao" ref="accountDao"/>
|
|
<property name="itemDao" ref="itemDao"/>
|
|
<!-- additional collaborators and configuration for this bean go here -->
|
|
</bean>
|
|
|
|
<!-- more bean definitions for services go here -->
|
|
|
|
</beans>
|
|
</programlisting>
|
|
|
|
<para>The following example shows the data access objects
|
|
<literal>daos.xml</literal> file:</para>
|
|
|
|
<programlisting language="xml"><?xml version="1.0" encoding="UTF-8"?>
|
|
<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">
|
|
|
|
<bean id="accountDao"
|
|
class="org.springframework.samples.jpetstore.dao.ibatis.SqlMapAccountDao">
|
|
<!-- additional collaborators and configuration for this bean go here -->
|
|
</bean>
|
|
|
|
<bean id="itemDao" class="org.springframework.samples.jpetstore.dao.ibatis.SqlMapItemDao">
|
|
<!-- additional collaborators and configuration for this bean go here -->
|
|
</bean>
|
|
|
|
<!-- more bean definitions for data access objects go here -->
|
|
|
|
</beans></programlisting>
|
|
|
|
<para>In the preceding example, the service layer consists of the class
|
|
<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 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><import/></literal> element to load
|
|
bean definitions from another file or files. For example:</para>
|
|
|
|
<programlisting language="xml"><beans>
|
|
|
|
<import resource="services.xml"/>
|
|
<import resource="resources/messageSource.xml"/>
|
|
<import resource="/resources/themeSource.xml"/>
|
|
|
|
<bean id="bean1" class="..."/>
|
|
<bean id="bean2" class="..."/>
|
|
|
|
</beans></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><beans/></literal> element, must be valid XML
|
|
bean definitions according to the Spring Schema or DTD.</para>
|
|
|
|
<note>
|
|
<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>
|
|
|
|
<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
|
|
such absolute locations, for example, through "${...}" placeholders
|
|
that are resolved against JVM system properties at runtime.</para>
|
|
</note>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="beans-factory-client">
|
|
<title>Using the container</title>
|
|
|
|
<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<T> requiredType)</methodname> you can
|
|
retrieve instances of your beans.</para>
|
|
|
|
<para>The <interfacename>ApplicationContext</interfacename> enables you 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 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>
|
|
</section>
|
|
|
|
<section id="beans-definition">
|
|
<title>Bean overview</title>
|
|
|
|
<para>A Spring IoC container manages one or more <emphasis>beans</emphasis>.
|
|
These beans are created with the configuration metadata that you supply to
|
|
the container, for example, in the form of XML
|
|
<literal><bean/></literal> definitions.</para>
|
|
|
|
<para>Within the container itself, these bean definitions are represented as
|
|
<interfacename>BeanDefinition</interfacename> objects, which contain
|
|
(among other information) the following metadata:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><emphasis>A package-qualified class name:</emphasis> typically the
|
|
actual implementation class of the bean being defined.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Bean behavioral configuration elements, which state how the bean
|
|
should behave in the container (scope, lifecycle callbacks, and so
|
|
forth).</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>References to other beans that are needed for the bean to do its
|
|
work; these references are also called
|
|
<emphasis>collaborators</emphasis> or
|
|
<emphasis>dependencies</emphasis>.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Other configuration settings to set in the newly created object,
|
|
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.</para>
|
|
|
|
<table id="beans-factory-bean-definition-tbl">
|
|
<title>The bean definition</title>
|
|
|
|
<tgroup cols="2">
|
|
<colspec colname="c1" colwidth="2*"/>
|
|
|
|
<colspec colname="c2" colwidth="4*"/>
|
|
|
|
<thead>
|
|
<row>
|
|
<entry>Property</entry>
|
|
|
|
<entry>Explained in...</entry>
|
|
</row>
|
|
</thead>
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry>class</entry>
|
|
|
|
<entry><para> <xref linkend="beans-factory-class"/> </para></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>name</entry>
|
|
|
|
<entry><para> <xref linkend="beans-beanname"/> </para></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>scope</entry>
|
|
|
|
<entry><para> <xref linkend="beans-factory-scopes"/> </para></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>constructor arguments</entry>
|
|
|
|
<entry><para> <xref linkend="beans-factory-collaborators"/>
|
|
</para></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>properties</entry>
|
|
|
|
<entry><para> <xref linkend="beans-factory-collaborators"/>
|
|
</para></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>autowiring mode</entry>
|
|
|
|
<entry><para> <xref linkend="beans-factory-autowire"/>
|
|
</para></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>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> implementations also
|
|
permit the registration of existing objects that are 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.</para>
|
|
|
|
<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
|
|
<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
|
|
introduce other aliases to the bean, you can also specify them in the
|
|
<literal>name</literal> attribute, separated by a comma
|
|
(<literal>,</literal>), semicolon (<literal>;</literal>), or white
|
|
space.</para>
|
|
|
|
<para>You are not required to supply 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 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>
|
|
|
|
<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
|
|
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 definitions. In XML-based
|
|
configuration metadata, you can use the
|
|
<literal><alias/></literal> element to accomplish this.</para>
|
|
|
|
<programlisting language="xml"><alias name="fromName" alias="toName"/></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>
|
|
|
|
<!-- MLP: Beverly to review -->
|
|
|
|
<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 DataSource
|
|
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>
|
|
|
|
<programlisting language="xml"><alias name="subsystemA-dataSource" alias="subsystemB-dataSource"/>
|
|
<alias name="subsystemA-dataSource" alias="myApp-dataSource" /></programlisting>
|
|
|
|
<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>
|
|
</section>
|
|
|
|
<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
|
|
<literal>class</literal> attribute of the
|
|
<literal><bean/></literal> element. This <literal>class</literal>
|
|
attribute, which internally is a <classname>Class</classname> property
|
|
on a <interfacename>BeanDefinition</interfacename> instance, is usually
|
|
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>
|
|
</listitem>
|
|
</itemizedlist></para>
|
|
|
|
<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>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<sidebar>
|
|
<title>Inner class names</title>
|
|
|
|
<para>If you want to configure a bean definition for a
|
|
<literal>static</literal> nested 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>
|
|
|
|
<section id="beans-factory-class-ctor">
|
|
<title>Instantiation with a constructor</title>
|
|
|
|
<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 use for
|
|
that specific bean, you may need a default (empty) constructor.</para>
|
|
|
|
<para>The Spring IoC container can manage virtually
|
|
<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
|
|
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>
|
|
|
|
<para>With XML-based configuration metadata you can specify your bean
|
|
class as follows:</para>
|
|
|
|
<programlisting language="xml"><bean id="exampleBean" class="examples.ExampleBean"/>
|
|
|
|
<bean name="anotherExample" class="examples.ExampleBeanTwo"/></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
|
|
linkend="beans-factory-collaborators">Injecting
|
|
Dependencies</link>.</para>
|
|
</section>
|
|
|
|
<section id="beans-factory-class-static-factory-method">
|
|
<title>Instantiation with a static factory method</title>
|
|
|
|
<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
|
|
<methodname>createInstance()</methodname> method must be a
|
|
<emphasis>static</emphasis> method.</para>
|
|
|
|
<programlisting language="xml"><bean id="clientService"
|
|
class="examples.ClientService"
|
|
factory-method="createInstance"/></programlisting>
|
|
|
|
<programlisting language="java">public class ClientService {
|
|
private static ClientService clientService = new ClientService();
|
|
private ClientService() {}
|
|
|
|
public static ClientService createInstance() {
|
|
return clientService;
|
|
}
|
|
}</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
|
|
linkend="beans-factory-properties-detailed">Dependencies and
|
|
configuration in detail</link>.</para>
|
|
</section>
|
|
|
|
<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>
|
|
|
|
<programlisting language="xml"><lineannotation><!-- the factory bean, which contains a method called <methodname>createInstance()</methodname> --></lineannotation>
|
|
<bean id="serviceLocator" class="examples.DefaultServiceLocator">
|
|
<lineannotation><!-- inject any dependencies required by this locator bean --></lineannotation>
|
|
</bean>
|
|
|
|
<lineannotation><!-- the bean to be created via the factory bean --></lineannotation>
|
|
<bean id="clientService"
|
|
factory-bean="serviceLocator"
|
|
factory-method="createClientServiceInstance"/></programlisting>
|
|
|
|
<programlisting language="java">public class DefaultServiceLocator {
|
|
private static ClientService clientService = new ClientServiceImpl();
|
|
private DefaultServiceLocator() {}
|
|
|
|
public ClientService createClientServiceInstance() {
|
|
return clientService;
|
|
}
|
|
}</programlisting>
|
|
|
|
<para>One factory class can also hold more than one factory method as
|
|
shown here:</para>
|
|
|
|
<programlisting language="xml">
|
|
<bean id="serviceLocator" class="examples.DefaultServiceLocator">
|
|
<lineannotation><!-- inject any dependencies required by this locator bean --></lineannotation>
|
|
</bean>
|
|
<bean id="clientService"
|
|
factory-bean="serviceLocator"
|
|
factory-method="createClientServiceInstance"/>
|
|
|
|
<bean id="accountService"
|
|
factory-bean="serviceLocator"
|
|
factory-method="createAccountServiceInstance"/></programlisting>
|
|
|
|
<programlisting language="java">public class DefaultServiceLocator {
|
|
private static ClientService clientService = new ClientServiceImpl();
|
|
private static AccountService accountService = new AccountServiceImpl();
|
|
|
|
private DefaultServiceLocator() {}
|
|
|
|
public ClientService createClientServiceInstance() {
|
|
return clientService;
|
|
}
|
|
|
|
public AccountService createAccountServiceInstance() {
|
|
return accountService;
|
|
}
|
|
}</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>
|
|
|
|
<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>
|
|
|
|
<xi:include href="beans-dependencies.xml"
|
|
xmlns:xi="http://www.w3.org/2001/XInclude"/>
|
|
|
|
<xi:include href="beans-scopes.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
|
|
|
|
<xi:include href="beans-customizing.xml"
|
|
xmlns:xi="http://www.w3.org/2001/XInclude"/>
|
|
|
|
<section id="beans-child-bean-definitions">
|
|
<title>Bean definition inheritance</title>
|
|
|
|
<para>A bean definition can contain a lot of configuration information,
|
|
including constructor arguments, property values, and container-specific
|
|
information such as initialization method, static factory method name, and
|
|
so on. A child bean definition inherits configuration data from a parent
|
|
definition. The child definition can override some values, or add others,
|
|
as needed. Using parent and child bean definitions can save a lot of
|
|
typing. Effectively, this is a form of templating.</para>
|
|
|
|
<para>If you work with an <interfacename>ApplicationContext</interfacename>
|
|
interface programmatically, child bean definitions are represented by the
|
|
<classname>ChildBeanDefinition</classname> class. Most users do not work
|
|
with them on this level, instead configuring bean definitions
|
|
declaratively in something like the
|
|
<classname>ClassPathXmlApplicationContext</classname>. When you use
|
|
XML-based configuration metadata, you indicate a child bean definition by
|
|
using the <literal>parent</literal> attribute, specifying the parent bean
|
|
as the value of this attribute.</para>
|
|
|
|
<programlisting language="xml"><bean id="inheritedTestBean" abstract="true"
|
|
class="org.springframework.beans.TestBean">
|
|
<property name="name" value="parent"/>
|
|
<property name="age" value="1"/>
|
|
</bean>
|
|
|
|
<bean id="inheritsWithDifferentClass"
|
|
class="org.springframework.beans.DerivedTestBean"
|
|
<emphasis role="bold">parent="inheritedTestBean"</emphasis> init-method="initialize">
|
|
|
|
<property name="name" value="override"/>
|
|
<lineannotation><!-- the age property value of 1 will be inherited from parent --></lineannotation>
|
|
|
|
</bean></programlisting>
|
|
|
|
<para>A child bean definition uses 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 inherits constructor argument values, property
|
|
values, and method overrides from the parent, with the option to add new
|
|
values. Any initialization method, destroy method, and/or
|
|
<literal>static</literal> factory method settings that you specify will
|
|
override the corresponding parent settings.</para>
|
|
|
|
<para>The remaining settings are <emphasis>always</emphasis> 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>The preceding example explicitly marks the parent bean definition as
|
|
abstract by using the <literal>abstract</literal> attribute. If the parent
|
|
definition does not specify a class, explicitly marking the parent bean
|
|
definition as <literal>abstract</literal> is required, as follows:</para>
|
|
|
|
<programlisting language="xml"><bean id="inheritedTestBeanWithoutClass" abstract="true">
|
|
<property name="name" value="parent"/>
|
|
<property name="age" value="1"/>
|
|
</bean>
|
|
|
|
<bean id="inheritsWithClass" class="org.springframework.beans.DerivedTestBean"
|
|
parent="inheritedTestBeanWithoutClass" init-method="initialize">
|
|
<property name="name" value="override"/>
|
|
<lineannotation><!-- age will inherit the value of <literal>1</literal> from the parent bean definition--></lineannotation>
|
|
</bean></programlisting>
|
|
|
|
<para>The parent bean cannot be instantiated on its own because it is
|
|
incomplete, and it is also explicitly marked as
|
|
<literal>abstract</literal>. When a definition is
|
|
<literal>abstract</literal> like this, it is usable only as a pure
|
|
template bean definition that serves 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, returns an error. Similarly, the container's internal
|
|
<methodname>preInstantiateSingletons()</methodname> method ignores bean
|
|
definitions that are defined as abstract.</para>
|
|
|
|
<note>
|
|
<para><literal>ApplicationContext</literal> pre-instantiates all
|
|
singletons by default. 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>
|
|
|
|
<xi:include href="beans-extension-points.xml"
|
|
xmlns:xi="http://www.w3.org/2001/XInclude"/>
|
|
|
|
<xi:include href="beans-annotation-config.xml"
|
|
xmlns:xi="http://www.w3.org/2001/XInclude"/>
|
|
|
|
<xi:include href="beans-classpath-scanning.xml"
|
|
xmlns:xi="http://www.w3.org/2001/XInclude"/>
|
|
|
|
<xi:include href="beans-java.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
|
|
|
|
<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.<!--Need to explain purpose of LoadTimeWeaver? Is this section ok here? --></para>
|
|
|
|
<programlisting language="xml"><beans>
|
|
|
|
<context:load-time-weaver/>
|
|
|
|
</beans></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>
|
|
|
|
<xi:include href="beans-context-additional.xml"
|
|
xmlns:xi="http://www.w3.org/2001/XInclude"/>
|
|
|
|
<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 <code>@PostConstruct</code> or
|
|
<code>@PreDestroy</code> in order to remain compatible with JDK 1.4 or to
|
|
avoid a dependency on JSR-250.</para>
|
|
|
|
<para>This section provides additional background into the differences
|
|
between the <interfacename>BeanFactory</interfacename> and
|
|
<interfacename>ApplicationContext</interfacename> and how one might access
|
|
the IoC container directly through a classic singleton lookup.</para>
|
|
|
|
<section id="context-introduction-ctx-vs-beanfactory">
|
|
<title><interfacename>BeanFactory</interfacename> or
|
|
<interfacename>ApplicationContext</interfacename>?</title>
|
|
|
|
<para>Use an <interfacename>ApplicationContext</interfacename> unless you
|
|
have a good reason for not doing so.</para>
|
|
|
|
<para>Because the <interfacename>ApplicationContext</interfacename>
|
|
includes all functionality of the
|
|
<interfacename>BeanFactory</interfacename>, it is generally recommended
|
|
over the <interfacename>BeanFactory</interfacename>, except for a few
|
|
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. Spring 2.0 and later makes
|
|
<emphasis>heavy</emphasis> use of the <link
|
|
linkend="beans-factory-extension-bpp"
|
|
><interfacename>BeanPostProcessor</interfacename> extension point</link>
|
|
(to effect proxying and so on). If you use only a plain
|
|
<interfacename>BeanFactory</interfacename>, a fair amount of support
|
|
such as transactions and AOP will not take effect, at least not without
|
|
some extra steps on your part. This situation could be confusing because
|
|
nothing is actually wrong with the configuration.</para>
|
|
|
|
<para>The following table lists features 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 with a
|
|
<interfacename>BeanFactory</interfacename> implementation, you must
|
|
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>To explicitly register a
|
|
<classname>BeanFactoryPostProcessor</classname> when using a
|
|
<interfacename>BeanFactory</interfacename> implementation, you must
|
|
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 inconvenient, which
|
|
is one reason 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>. These mechanisms implement
|
|
important functionality such as property placeholder replacement and
|
|
AOP.</para>
|
|
</section>
|
|
|
|
<section id="beans-servicelocator">
|
|
<title>Glue code and the evil singleton</title>
|
|
|
|
<para>It is best to write most application code in a dependency-injection
|
|
(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, you
|
|
sometimes need a 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 get these objects out of a Spring IoC container.
|
|
<!--Can you reword the phrase singleton style access, above and next parragraph? Seems awkward.-->If
|
|
the object constructed by the third-party code is 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, retrieved from 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 for accessing shared Spring-managed
|
|
components, such as in an EJB 2.1 environment, or when 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>
|
|
</chapter>
|