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.
520 lines
27 KiB
XML
520 lines
27 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
|
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
|
<section id="beans-factory-extension">
|
|
<title>Container extension points</title>
|
|
|
|
<para>Typically, an application developer does not need to subclass any
|
|
<interfacename>ApplicationContext</interfacename> implementation classes.
|
|
You can extend The Spring IoC container infinitely by plugging in
|
|
implementations of special integration interfaces. The next few sections
|
|
describe these integration interfaces.</para>
|
|
|
|
<section id="beans-factory-extension-bpp">
|
|
<title>Customizing beans using the
|
|
<interfacename>BeanPostProcessor</interfacename> Interface <literal>
|
|
</literal></title>
|
|
|
|
<para>The <interfacename>BeanPostProcessor</interfacename> interface defines
|
|
<firstterm>callback methods</firstterm> that you can implement to provide
|
|
your own (or override the container's default) instantiation logic,
|
|
dependency-resolution logic, and so forth. If you want to implement some
|
|
custom logic after the Spring container finishes instantiating,
|
|
configuring, and otherwise initializing a bean, you can plug in one or
|
|
more <interfacename>BeanPostProcessor</interfacename>
|
|
implementations.</para>
|
|
|
|
<para>You can configure multiple <literal>BeanPostProcessor</literal>
|
|
interfaces. You can control the order in which these
|
|
<literal>BeanPostProcessor</literal> interfaces execute by setting the
|
|
<literal>order</literal> property. You can set this property only if the
|
|
<interfacename>BeanPostProcessor</interfacename> implements the
|
|
<interfacename>Ordered</interfacename> interface; if you write your own
|
|
<interfacename>BeanPostProcessor</interfacename> you should consider
|
|
implementing the <interfacename>Ordered</interfacename> interface too. For
|
|
more details, consult the Javadoc for the
|
|
<interfacename>BeanPostProcessor</interfacename> and
|
|
<interfacename>Ordered</interfacename> interfaces.</para>
|
|
|
|
<note>
|
|
<para><literal>BeanPostProcessor</literal>s operate on bean (or object)
|
|
<emphasis>instances</emphasis>; that is to say, the Spring IoC container
|
|
instantiates a bean instance and <emphasis>then</emphasis>
|
|
<literal>BeanPostProcessor</literal> interfaces do their work.</para>
|
|
|
|
<para><literal>BeanPostProcessor</literal> interfaces are scoped
|
|
<emphasis>per-container</emphasis>. This is only relevant if you are
|
|
using container hierarchies. If you define a
|
|
<interfacename>BeanPostProcessor</interfacename> in one container, it
|
|
will <emphasis>only</emphasis> do its work on the beans in that
|
|
container. Beans that are defined in one container are not
|
|
post-processed by a <literal>BeanPostProcessor</literal> in another
|
|
container, even if both containers are part of the same
|
|
hierarchy.</para>
|
|
|
|
<para>To change the actual bean definition (that is, the recipe that
|
|
defines the bean), you instead need to use a
|
|
<interfacename>BeanFactoryPostProcessor</interfacename>, described below
|
|
in <xref linkend="beans-factory-extension-factory-postprocessors"
|
|
/>.</para>
|
|
</note>
|
|
|
|
<para>The
|
|
<interfacename>org.springframework.beans.factory.config.BeanPostProcessor</interfacename>
|
|
interface consists of exactly two callback methods. When such a class is
|
|
registered as a post-processor with the container, for each bean instance
|
|
that is created by the container, the post-processor gets a callback from
|
|
the container both <emphasis>before</emphasis> container initialization
|
|
methods (such as <emphasis>afterPropertiesSet</emphasis> and any declared
|
|
init method) are called, and also afterwards. The post-processor can take
|
|
any action with the bean instance, including ignoring the callback
|
|
completely. A bean post-processor typically checks for callback
|
|
interfaces, or may wrap a bean with a proxy. Some Spring AOP
|
|
infrastructure classes are implemented as bean post-processors and they do
|
|
this proxy-wrapping logic.</para>
|
|
|
|
<para>An <interfacename>ApplicationContext</interfacename>
|
|
<emphasis>automatically detects</emphasis> any beans that are defined in
|
|
the configuration metadata it receives that implement the
|
|
<interfacename>BeanPostProcessor</interfacename> interface. The
|
|
<interfacename>ApplicationContext</interfacename> registers these beans as
|
|
post-processors, to be then called appropriately by the container upon
|
|
bean creation. You can then deploy the post-processors as you would any
|
|
bean.</para>
|
|
|
|
<note>
|
|
<title><interfacename>BeanPostProcessors</interfacename> and AOP
|
|
auto-proxying</title>
|
|
|
|
<para>Classes that implement the
|
|
<interfacename>BeanPostProcessor</interfacename> interface are
|
|
<emphasis>special</emphasis>, and so they are treated differently by the
|
|
container. All <interfacename>BeanPostProcessors</interfacename>
|
|
<emphasis>and their directly referenced beans</emphasis> are
|
|
instantiated on startup, as part of the special startup phase of the
|
|
<interfacename>ApplicationContext</interfacename>. Next, all those
|
|
<interfacename>BeanPostProcessors</interfacename> are registered in a
|
|
sorted fashion - and applied to all further beans. Because AOP
|
|
auto-proxying is implemented as a
|
|
<interfacename>BeanPostProcessor</interfacename> itself, no
|
|
<interfacename>BeanPostProcessors</interfacename> or directly referenced
|
|
beans are eligible for auto-proxying, and thus do not have aspects woven
|
|
into them.</para>
|
|
|
|
<para>For any such bean, you should see an info log message:
|
|
<emphasis><quote>Bean foo is not eligible for getting processed by all
|
|
BeanPostProcessor interfaces (for example: not eligible for
|
|
auto-proxying)</quote>.</emphasis></para>
|
|
</note>
|
|
|
|
<para>The following examples show how to write, register, and use
|
|
<literal>BeanPostProcessors</literal> in the context of an
|
|
<interfacename>ApplicationContext</interfacename>.</para>
|
|
|
|
<section id="beans-factory-extension-bpp-examples-hw">
|
|
<title>Example: Hello World,
|
|
<interfacename>BeanPostProcessor</interfacename>-style</title>
|
|
|
|
<para>This first example illustrates basic usage. The example shows a
|
|
custom <interfacename>BeanPostProcessor</interfacename> implementation
|
|
that invokes the <methodname>toString()</methodname> method of each bean
|
|
as it is created by the container and prints the resulting string to the
|
|
system console.</para>
|
|
|
|
<para>Find below the custom
|
|
<interfacename>BeanPostProcessor</interfacename> implementation class
|
|
definition:</para>
|
|
|
|
<programlisting language="java">package scripting;
|
|
|
|
import org.springframework.beans.factory.config.BeanPostProcessor;
|
|
import org.springframework.beans.BeansException;
|
|
|
|
public class InstantiationTracingBeanPostProcessor implements BeanPostProcessor {
|
|
|
|
<lineannotation>// simply return the instantiated bean as-is</lineannotation>
|
|
public Object postProcessBeforeInitialization(Object bean, String beanName)
|
|
throws BeansException {
|
|
return bean; <lineannotation>// we could potentially return <emphasis>any</emphasis> object reference here...</lineannotation>
|
|
}
|
|
|
|
public Object postProcessAfterInitialization(Object bean, String beanName)
|
|
throws BeansException {
|
|
System.out.println("Bean '" + beanName + "' created : " + bean.toString());
|
|
return bean;
|
|
}
|
|
}</programlisting>
|
|
|
|
<programlisting language="xml"><?xml version="1.0" encoding="UTF-8"?>
|
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xmlns:lang="http://www.springframework.org/schema/lang"
|
|
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
|
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
|
http://www.springframework.org/schema/lang
|
|
http://www.springframework.org/schema/lang/spring-lang-3.0.xsd">
|
|
|
|
<lang:groovy id="messenger"
|
|
script-source="classpath:org/springframework/scripting/groovy/Messenger.groovy">
|
|
<lang:property name="message" value="Fiona Apple Is Just So Dreamy."/>
|
|
</lang:groovy>
|
|
|
|
<lineannotation><!--
|
|
when the above bean (messenger) is instantiated, this custom
|
|
<interfacename>BeanPostProcessor</interfacename> implementation will output the fact to the system console
|
|
--></lineannotation>
|
|
<bean class="scripting.InstantiationTracingBeanPostProcessor"/>
|
|
|
|
</beans></programlisting>
|
|
|
|
<para>Notice how the
|
|
<classname>InstantiationTracingBeanPostProcessor</classname> is simply
|
|
defined. It does not even have a name, and because it is a bean it can
|
|
be dependency-injected just like any other bean. (The preceding
|
|
configuration also defines a bean that is backed by a Groovy script. The
|
|
Spring 2.0 dynamic language support is detailed in the chapter entitled
|
|
<xref linkend="dynamic-language"/>.)</para>
|
|
|
|
<para>The following small driver script executes the preceding code and
|
|
configuration:</para>
|
|
|
|
<programlisting language="java">import org.springframework.context.ApplicationContext;
|
|
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
|
import org.springframework.scripting.Messenger;
|
|
|
|
public final class Boot {
|
|
|
|
public static void main(final String[] args) throws Exception {
|
|
ApplicationContext ctx = new ClassPathXmlApplicationContext("scripting/beans.xml");
|
|
Messenger messenger = (Messenger) ctx.getBean("messenger");
|
|
System.out.println(messenger);
|
|
}
|
|
}</programlisting>
|
|
|
|
<para>The output of the preceding execution resembles the
|
|
following:</para>
|
|
|
|
<programlisting>Bean 'messenger' created : org.springframework.scripting.groovy.GroovyMessenger@272961
|
|
org.springframework.scripting.groovy.GroovyMessenger@272961</programlisting>
|
|
</section>
|
|
|
|
<section id="beans-factory-extension-bpp-examples-rabpp">
|
|
<title>Example: The
|
|
<classname>RequiredAnnotationBeanPostProcessor</classname></title>
|
|
|
|
<para>Using callback interfaces or annotations in conjunction with a
|
|
custom <interfacename>BeanPostProcessor</interfacename> implementation
|
|
is a common means of extending the Spring IoC container. An example is
|
|
Spring's <classname>RequiredAnnotationBeanPostProcessor</classname> -- a
|
|
<interfacename>BeanPostProcessor</interfacename> implementation that
|
|
ships with the Spring distribution which ensures that JavaBean
|
|
properties on beans that are marked with an (arbitrary) annotation are
|
|
actually (configured to be) dependency-injected with a value.</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="beans-factory-extension-factory-postprocessors">
|
|
<title>Customizing configuration metadata with
|
|
<interfacename>BeanFactoryPostProcessor</interfacename> interface</title>
|
|
|
|
<para>The next extension point that we will look at is the
|
|
<interfacename>org.springframework.beans.factory.config.BeanFactoryPostProcessor</interfacename>.
|
|
The semantics of this interface are similar to the
|
|
<interfacename>BeanPostProcessor</interfacename>, with one major
|
|
difference: <literal>BeanFactoryPostProcessor</literal>s operate on the
|
|
<emphasis>bean configuration metadata</emphasis>; that is, the Spring IoC
|
|
container allows <literal>BeanFactoryPostProcessors</literal> to read the
|
|
configuration metadata and potentially change it
|
|
<emphasis>before</emphasis> the container instantiates any beans other
|
|
than <literal>BeanFactoryPostProcessors</literal>.</para>
|
|
|
|
<para>You can configure multiple
|
|
<literal>BeanFactoryPostProcessors</literal>. You can control the order in
|
|
which these <literal>BeanFactoryPostProcessors</literal> execute by
|
|
setting the <literal>order</literal> property. However, you can only set
|
|
this property if the
|
|
<interfacename>BeanFactoryPostProcessor</interfacename> implements the
|
|
<interfacename>Ordered</interfacename> interface. If you write your own
|
|
<interfacename>BeanFactoryPostProcessor,</interfacename> you should
|
|
consider implementing the <interfacename>Ordered</interfacename> interface
|
|
too; consult the Javadoc for the
|
|
<interfacename>BeanFactoryPostProcessor</interfacename> and
|
|
<interfacename>Ordered</interfacename> interfaces for more details.</para>
|
|
|
|
<note>
|
|
<para>If you want to change the actual bean <emphasis>instances</emphasis>
|
|
(the objects that are created from the configuration metadata), then you
|
|
instead need to use a <interfacename>BeanPostProcessor</interfacename>
|
|
(described above in <xref linkend="beans-factory-extension-bpp"/>. While
|
|
it is technically possible to work with bean instances within a
|
|
<interfacename>BeanFactoryPostProcessor</interfacename> (e.g. using
|
|
<methodname>BeanFactory.getBean()</methodname>), doing so causes
|
|
premature bean instantiation, violating the usual containter lifecycle.
|
|
This may cause negative side effects such as bypassing bean post
|
|
processing.</para>
|
|
|
|
<para>Also, <literal>BeanFactoryPostProcessors</literal> are scoped
|
|
<emphasis>per-container</emphasis>. This is only relevant if you are
|
|
using container hierarchies. If you define a
|
|
<interfacename>BeanFactoryPostProcessor</interfacename> in one
|
|
container, it will <emphasis>only</emphasis> do its stuff on the bean
|
|
definitions in that container. Bean definitions in another container
|
|
will not be post-processed by
|
|
<literal>BeanFactoryPostProcessors</literal> in another container, even
|
|
if both containers are part of the same hierarchy.</para>
|
|
</note>
|
|
|
|
<para>A bean factory post-processor is executed automatically when it is
|
|
declared inside of an <interfacename>ApplicationContext,</interfacename>
|
|
in order to apply changes to the configuration metadata that defines a
|
|
container. Spring includes a number of pre-existing bean factory
|
|
post-processors, such as <classname>PropertyOverrideConfigurer</classname>
|
|
and <classname>PropertyPlaceholderConfigurer. </classname>A custom
|
|
<interfacename>BeanFactoryPostProcessor</interfacename> can also be used,
|
|
for example, to register custom property editors.</para>
|
|
|
|
<anchor id="beans-factory-autodetect-beanfactorypostprocessors"/>
|
|
|
|
<para>An <interfacename>ApplicationContext</interfacename> detects any beans
|
|
that are deployed into it and that implement the
|
|
<interfacename>BeanFactoryPostProcessor</interfacename> interface. It
|
|
automatically uses these beans as bean factory post-processors, at the
|
|
appropriate time. You can then deploy these post-processor beans as you
|
|
would any other bean.</para>
|
|
|
|
<note>
|
|
<para>As with <literal>BeanPostProcessors</literal>, you typically do not
|
|
want <literal>BeanFactoryPostProcessors</literal> marked as
|
|
lazy-initialized. If they are marked as such, the Spring container never
|
|
instantiates them, and thus they cannot apply their custom logic. If you
|
|
use the <literal>default-lazy-init</literal> attribute on the
|
|
declaration of your <literal><beans/></literal> element, be sure
|
|
to mark your various
|
|
<interfacename>BeanFactoryPostProcessor</interfacename> bean definitions
|
|
with <literal>lazy-init="false"</literal>.</para>
|
|
</note>
|
|
|
|
<section id="beans-factory-placeholderconfigurer">
|
|
<title>Example: the
|
|
<interfacename>PropertyPlaceholderConfigurer</interfacename></title>
|
|
|
|
<para>You use the
|
|
<interfacename>PropertyPlaceholderConfigurer</interfacename> to
|
|
externalize property values from a bean definition into another separate
|
|
file in the standard Java <classname>Properties</classname> format.
|
|
Doing so enables the person deploying an application to customize
|
|
environment-specific properties such as database URLs and passwords,
|
|
without the complexity or risk of modifying the main XML definition file
|
|
or files for the container.</para>
|
|
|
|
<!-- MLP: Beverly to review following 2 paragraphs -->
|
|
|
|
<para>Consider the following XML-based configuration metadata fragment,
|
|
where a <interfacename>DataSource</interfacename> with placeholder
|
|
values is defined. The example shows properties configured from an
|
|
external <classname>Properties</classname> file. At runtime, a
|
|
<classname>PropertyPlaceholderConfigurer</classname> is applied to the
|
|
metadata that will replace some properties of the DataSource. The values
|
|
to replace are specified as 'placeholders' of the form ${property-name}
|
|
which follows the Ant / Log4J / JSP EL style.</para>
|
|
|
|
<programlisting language="xml"><bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
|
|
<property name="locations" value="classpath:com/foo/jdbc.properties"/>
|
|
</bean>
|
|
|
|
<bean id="dataSource" destroy-method="close"
|
|
class="org.apache.commons.dbcp.BasicDataSource">
|
|
<property name="driverClassName" value="<emphasis role="bold">${jdbc.driverClassName}</emphasis>"/>
|
|
<property name="url" value="<emphasis role="bold">${jdbc.url}</emphasis>"/>
|
|
<property name="username" value="<emphasis role="bold">${jdbc.username}</emphasis>"/>
|
|
<property name="password" value="<emphasis role="bold">${jdbc.password}</emphasis>"/>
|
|
</bean></programlisting>
|
|
|
|
<para>The actual values come from another file in the standard Java
|
|
<classname>Properties</classname> format:</para>
|
|
|
|
<programlisting language="java">jdbc.driverClassName=org.hsqldb.jdbcDriver
|
|
jdbc.url=jdbc:hsqldb:hsql://production:9002
|
|
jdbc.username=sa
|
|
jdbc.password=root</programlisting>
|
|
|
|
<para>Therefore, the string ${jdbc.username} is replaced at runtime with
|
|
the value 'sa' and similarly for other placeholder values that match to
|
|
keys in the property file. The PropertyPlaceholderConfigurer checks for
|
|
placeholders in most locations of a bean definition and the placeholder
|
|
prefix and suffix can be customized.</para>
|
|
|
|
<para>With the <literal>context</literal> namespace introduced in Spring
|
|
2.5, it is possible to configure property placeholders with a dedicated
|
|
configuration element. You can provide multiple locations as a
|
|
comma-separated list in the <literal>location</literal>
|
|
attribute.</para>
|
|
|
|
<programlisting language="xml"><context:property-placeholder location="classpath:com/foo/jdbc.properties"/></programlisting>
|
|
|
|
<para>The <classname>PropertyPlaceholderConfigurer</classname> does not
|
|
look for properties only in the <classname>Properties</classname> file
|
|
you specify, but also checks against the Java
|
|
<classname>System</classname> properties if it cannot find a property
|
|
you are trying to use. You can customize this behavior by setting the
|
|
<literal>systemPropertiesMode</literal> property of the configurer. It
|
|
has three values that specify configurer behavior: always override,
|
|
<emphasis>never</emphasis> override, and override only if the property
|
|
is not found in the properties file specified.
|
|
<!--What property is it overriding and what will replace the overridden value?-->
|
|
<!--MLP: override a value in the Properties with one from the 'systemProperties' -->
|
|
Consult the Javadoc for the
|
|
<classname>PropertyPlaceholderConfigurer</classname> for more
|
|
information.</para>
|
|
|
|
<tip>
|
|
<title>Class name substitution</title>
|
|
|
|
<para>You can use the
|
|
<classname>PropertyPlaceholderConfigurer</classname> to substitute
|
|
class names, which is sometimes useful when you have to pick a
|
|
particular implementation class at runtime. For example:</para>
|
|
|
|
<programlisting language="xml"><bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
|
|
<property name="locations">
|
|
<value>classpath:com/foo/strategy.properties</value>
|
|
</property>
|
|
<property name="properties">
|
|
<value>custom.strategy.class=com.foo.DefaultStrategy</value>
|
|
</property>
|
|
</bean>
|
|
|
|
<bean id="serviceStrategy" class="${custom.strategy.class}"/></programlisting>
|
|
|
|
<para>If the class cannot be resolved at runtime to a valid class,
|
|
resolution of the bean fails when it is about to be created, which is
|
|
during the <methodname>preInstantiateSingletons()</methodname> phase
|
|
of an <interfacename>ApplicationContext</interfacename> for a
|
|
non-lazy-init bean.</para>
|
|
</tip>
|
|
</section>
|
|
|
|
<section id="beans-factory-overrideconfigurer">
|
|
<title>Example: the
|
|
<classname>PropertyOverrideConfigurer</classname></title>
|
|
|
|
<para>The <classname>PropertyOverrideConfigurer</classname>, another bean
|
|
factory post-processor, resembles the
|
|
<interfacename>PropertyPlaceholderConfigurer</interfacename>, but unlike
|
|
the latter, the original definitions can have default values or no
|
|
values at all for bean properties. If an overriding
|
|
<classname>Properties</classname> file does not have an entry for a
|
|
certain bean property, the default context definition is used.</para>
|
|
|
|
<para>Note that the bean definition is <emphasis>not</emphasis> aware of
|
|
being overridden, so it is not immediately obvious from the XML
|
|
definition file that the override configurer is used. In case of
|
|
multiple <classname>PropertyOverrideConfigurer</classname> instances
|
|
that define different values for the same bean property, the last one
|
|
wins, due to the overriding mechanism.</para>
|
|
|
|
<para>Properties file configuration lines take this format:</para>
|
|
|
|
<programlisting language="java">beanName.property=value</programlisting>
|
|
|
|
<para>For example:</para>
|
|
|
|
<programlisting language="java">dataSource.driverClassName=com.mysql.jdbc.Driver
|
|
dataSource.url=jdbc:mysql:mydb</programlisting>
|
|
|
|
<para>This example file is usable against a container definition that
|
|
contains a bean called <emphasis>dataSource</emphasis>, which has
|
|
<emphasis>driver</emphasis> and <emphasis>url</emphasis>
|
|
properties.</para>
|
|
|
|
<para>Compound property names are also supported, as long as every
|
|
component of the path except the final property being overridden is
|
|
already non-null (presumably initialized by the constructors). In this
|
|
example...</para>
|
|
|
|
<programlisting language="java">foo.fred.bob.sammy=123</programlisting>
|
|
|
|
<para>... the <literal>sammy</literal> property of the
|
|
<literal>bob</literal> property of the <literal>fred</literal> property
|
|
of the <literal>foo</literal> bean is set to the scalar value
|
|
<literal>123</literal>.</para>
|
|
|
|
<para><note>
|
|
<para>Specified override values are always <emphasis>literal</emphasis>
|
|
values; they are not translated into bean references. This convention
|
|
also applies when the original value in the XML bean definition
|
|
specifies a bean reference.</para>
|
|
</note></para>
|
|
|
|
<para>With the <literal>context</literal> namespace introduced in Spring
|
|
2.5, it is possible to configure property overriding with a dedicated
|
|
configuration element:</para>
|
|
|
|
<programlisting language="xml"><context:property-override location="classpath:override.properties"/></programlisting>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="beans-factory-extension-factorybean">
|
|
<title>Customizing instantiation logic with the
|
|
<interfacename>FactoryBean</interfacename> Interface <literal>
|
|
</literal></title>
|
|
|
|
<para>You implement the
|
|
<interfacename>org.springframework.beans.factory.FactoryBean</interfacename>
|
|
interface for objects that <emphasis>are themselves
|
|
factories</emphasis>.</para>
|
|
|
|
<para>The <interfacename>FactoryBean</interfacename> interface is a point of
|
|
pluggability into the Spring IoC container's instantiation logic. If you
|
|
have complex initialization code that is better expressed in Java as
|
|
opposed to a (potentially) verbose amount of XML, you can create your own
|
|
<interfacename>FactoryBean</interfacename>, write the complex
|
|
initialization inside that class, and then plug your custom
|
|
<interfacename>FactoryBean</interfacename> into the container.</para>
|
|
|
|
<para>The <interfacename>FactoryBean</interfacename> interface provides
|
|
three methods:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><methodname>Object getObject()</methodname>: returns an instance
|
|
of the object this factory creates. The instance can possibly be
|
|
shared, depending on whether this factory returns singletons or
|
|
prototypes.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para><methodname>boolean isSingleton()</methodname>: returns
|
|
<literal>true</literal> if this
|
|
<interfacename>FactoryBean</interfacename> returns singletons,
|
|
<literal>false</literal> otherwise.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para><methodname>Class getObjectType()</methodname>: returns the object
|
|
type returned by the <methodname>getObject()</methodname> method or
|
|
<literal>null</literal> if the type is not known in advance</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>The <interfacename>FactoryBean</interfacename> concept and interface
|
|
is used in a number of places within the Spring Framework; more than 50
|
|
implementations of the <interfacename>FactoryBean</interfacename>
|
|
interface ship with Spring itself.</para>
|
|
|
|
<para>When you need to ask a container for an actual
|
|
<interfacename>FactoryBean</interfacename> instance itself, not the bean
|
|
it produces, you preface the bean id with the ampersand symbol
|
|
<literal>&</literal> (without quotes) when calling the
|
|
<methodname>getBean()</methodname> method of the
|
|
<interfacename>ApplicationContext</interfacename>. So for a given
|
|
<interfacename>FactoryBean</interfacename> with an id of
|
|
<literal>myBean</literal>, invoking <literal>getBean("myBean")</literal>
|
|
on the container returns the product of the
|
|
<interfacename>FactoryBean</interfacename>, and invoking
|
|
<literal>getBean("&myBean")</literal> returns the
|
|
<interfacename>FactoryBean</interfacename> instance
|
|
itself.<!--Moved ApplicationContext section to almost the end of the doc, right before BeanFactory and renamed it Additional Capabilities of.--></para>
|
|
</section>
|
|
</section>
|