You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
519 lines
27 KiB
519 lines
27 KiB
<?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>
|
|
|