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>
|