From f78d0a4afc8546229dfe1e166f05ad32face42c2 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 30 Dec 2010 02:07:22 +0000 Subject: [PATCH] [SPR-7848] Improved readability, grammar, and formatting of the Container Extension Points section of the reference manual. git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@3835 50f2f4bb-b051-0410-bef5-90022cba6387 --- .../src/beans-extension-points.xml | 227 +++++++++--------- 1 file changed, 120 insertions(+), 107 deletions(-) diff --git a/spring-framework-reference/src/beans-extension-points.xml b/spring-framework-reference/src/beans-extension-points.xml index 1bcc09886af..a65097150e0 100644 --- a/spring-framework-reference/src/beans-extension-points.xml +++ b/spring-framework-reference/src/beans-extension-points.xml @@ -2,37 +2,36 @@
- Container extension points + Container Extension Points - Typically, an application developer does not need to subclass any + Typically, an application developer does not need to subclass ApplicationContext implementation classes. - You can extend The Spring IoC container infinitely by plugging in + Instead, the Spring IoC container can be extended by plugging in implementations of special integration interfaces. The next few sections describe these integration interfaces.
- Customizing beans using the - <interfacename>BeanPostProcessor</interfacename> Interface <literal> - </literal> + Customizing beans using a + <interfacename>BeanPostProcessor</interfacename> The BeanPostProcessor interface defines callback methods 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 + configuring, and initializing a bean, you can plug in one or more BeanPostProcessor implementations. You can configure multiple BeanPostProcessor - interfaces. You can control the order in which these - BeanPostProcessor interfaces execute by setting the + instances, and you can control the order in which these + BeanPostProcessors execute by setting the order property. You can set this property only if the BeanPostProcessor implements the Ordered interface; if you write your own BeanPostProcessor you should consider implementing the Ordered interface too. For - more details, consult the Javadoc for the + further details, consult the Javadoc for the BeanPostProcessor and Ordered interfaces. @@ -40,21 +39,20 @@ BeanPostProcessors operate on bean (or object) instances; that is to say, the Spring IoC container instantiates a bean instance and then - BeanPostProcessor interfaces do their work. + BeanPostProcessors do their work. - BeanPostProcessor interfaces are scoped + BeanPostProcessors are scoped per-container. This is only relevant if you are using container hierarchies. If you define a BeanPostProcessor in one container, it - will only do its work on the beans in that - container. Beans that are defined in one container are not - post-processed by a BeanPostProcessor in another - container, even if both containers are part of the same - hierarchy. + will only post-process the beans in that + container. In other words, beans that are defined in one container are not + post-processed by a BeanPostProcessor defined in another + container, even if both containers are part of the same hierarchy. - To change the actual bean definition (that is, the recipe that - defines the bean), you instead need to use a - BeanFactoryPostProcessor, described below + To change the actual bean definition (i.e., the + blueprint that defines the bean), you instead need to use a + BeanFactoryPostProcessor as described in . @@ -65,22 +63,23 @@ 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 before container initialization - methods (such as afterPropertiesSet and any declared - init method) are called, and also afterwards. The post-processor can take + methods (such as InitializingBean's afterPropertiesSet() + and any declared init method) are called as well as after + any bean initialization callbacks. 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. + interfaces or may wrap a bean with a proxy. Some Spring AOP + infrastructure classes are implemented as bean post-processors in order + to provide proxy-wrapping logic. An ApplicationContext automatically detects any beans that are defined in - the configuration metadata it receives that implement the + the configuration metadata which implement the BeanPostProcessor interface. The ApplicationContext 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. + post-processors so that they can be called later upon bean creation. + Bean post-processors can be deployed in the container just like any other + beans. <interfacename>BeanPostProcessors</interfacename> and AOP @@ -88,27 +87,27 @@ <para>Classes that implement the <interfacename>BeanPostProcessor</interfacename> interface are - <emphasis>special</emphasis>, and so they are treated differently by the + <emphasis>special</emphasis> and are treated differently by the container. All <interfacename>BeanPostProcessors</interfacename> - <emphasis>and their directly referenced beans</emphasis> are + <emphasis>and beans that they reference directly</emphasis> are instantiated on startup, as part of the special startup phase of the - <interfacename>ApplicationContext</interfacename>. Next, all those + <interfacename>ApplicationContext</interfacename>. Next, all <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 + sorted fashion and applied to all further beans in the container. + Because AOP auto-proxying is implemented as a + <interfacename>BeanPostProcessor</interfacename> itself, neither + <interfacename>BeanPostProcessors</interfacename> nor the beans they reference + directly 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 + <para>For any such bean, you should see an informational log message: + <quote><emphasis>Bean foo is not eligible for getting processed by all BeanPostProcessor interfaces (for example: not eligible for - auto-proxying)</quote>.</emphasis></para> + auto-proxying)</emphasis></quote>.</para> </note> <para>The following examples show how to write, register, and use - <literal>BeanPostProcessors</literal> in the context of an + <literal>BeanPostProcessors</literal> in an <interfacename>ApplicationContext</interfacename>.</para> <section id="beans-factory-extension-bpp-examples-hw"> @@ -175,7 +174,7 @@ public class InstantiationTracingBeanPostProcessor implements BeanPostProcessor 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 + <para>The following simple Java application executes the preceding code and configuration:</para> <programlisting language="java">import org.springframework.context.ApplicationContext; @@ -191,7 +190,7 @@ public final class Boot { } }</programlisting> - <para>The output of the preceding execution resembles the + <para>The output of the preceding application resembles the following:</para> <programlisting>Bean 'messenger' created : org.springframework.scripting.groovy.GroovyMessenger@272961 @@ -205,7 +204,7 @@ org.springframework.scripting.groovy.GroovyMessenger@272961</programlisting> <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 + 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 @@ -214,12 +213,12 @@ org.springframework.scripting.groovy.GroovyMessenger@272961</programlisting> </section> <section id="beans-factory-extension-factory-postprocessors"> - <title>Customizing configuration metadata with - <interfacename>BeanFactoryPostProcessor</interfacename> interface + Customizing configuration metadata with a + <interfacename>BeanFactoryPostProcessor</interfacename> The next extension point that we will look at is the org.springframework.beans.factory.config.BeanFactoryPostProcessor. - The semantics of this interface are similar to the + The semantics of this interface are similar to those of the BeanPostProcessor, with one major difference: BeanFactoryPostProcessors operate on the bean configuration metadata; that is, the Spring IoC @@ -229,27 +228,27 @@ org.springframework.scripting.groovy.GroovyMessenger@272961 than BeanFactoryPostProcessors. You can configure multiple - BeanFactoryPostProcessors. You can control the order in + BeanFactoryPostProcessors, and you can control the order in which these BeanFactoryPostProcessors execute by setting the order property. However, you can only set this property if the BeanFactoryPostProcessor implements the Ordered interface. If you write your own - BeanFactoryPostProcessor, you should + BeanFactoryPostProcessor, you should consider implementing the Ordered interface - too; consult the Javadoc for the + too. Consult the Javadoc for the BeanFactoryPostProcessor and Ordered interfaces for more details. If you want to change the actual bean instances - (the objects that are created from the configuration metadata), then you + (i.e., the objects that are created from the configuration metadata), then you instead need to use a BeanPostProcessor - (described above in . While + (described above in ). While it is technically possible to work with bean instances within a - BeanFactoryPostProcessor (e.g. using + BeanFactoryPostProcessor (e.g., using BeanFactory.getBean()), doing so causes - premature bean instantiation, violating the usual containter lifecycle. + premature bean instantiation, violating the standard container lifecycle. This may cause negative side effects such as bypassing bean post processing. @@ -257,40 +256,42 @@ org.springframework.scripting.groovy.GroovyMessenger@272961 per-container. This is only relevant if you are using container hierarchies. If you define a BeanFactoryPostProcessor in one - container, it will only do its stuff on the bean - definitions in that container. Bean definitions in another container + container, it will only be applied to the bean + definitions in that container. Bean definitions in one container will not be post-processed by BeanFactoryPostProcessors in another container, even if both containers are part of the same hierarchy. A bean factory post-processor is executed automatically when it is - declared inside of an ApplicationContext, - in order to apply changes to the configuration metadata that defines a - container. Spring includes a number of pre-existing bean factory + declared inside an ApplicationContext, + in order to apply changes to the configuration metadata that define the + container. Spring includes a number of predefined bean factory post-processors, such as PropertyOverrideConfigurer - and PropertyPlaceholderConfigurer. A custom + and PropertyPlaceholderConfigurer. A custom BeanFactoryPostProcessor can also be used, for example, to register custom property editors. - An ApplicationContext detects any beans - that are deployed into it and that implement the + An ApplicationContext automatically + detects any beans that are deployed into it that implement the BeanFactoryPostProcessor 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 + uses these beans as bean factory post-processors, at the + appropriate time. You can deploy these post-processor beans as you would any other bean. - As with BeanPostProcessors, you typically - do not want BeanFactoryPostProcessors marked as - lazy-initialized. If no other bean references a Bean(Factory)PostProcessor - those wouldn't get instantiated at all. Thus, marking them as - lazy-initialized will be ignored and the Bean(Factory)PostProcessor - will be instantied eagerly even if you use the default-lazy-init - attribute set to trueon the declaration of your - element. + As with BeanPostProcessors, you typically + do not want to configure BeanFactoryPostProcessors + for lazy initialization. If no other bean references a + Bean(Factory)PostProcessor, + that post-processor will not get instantiated at all. Thus, marking it for + lazy initialization will be ignored, and the + Bean(Factory)PostProcessor will be + instantiated eagerly even if you set the default-lazy-init + attribute to true on the declaration of your + <beans /> element.
@@ -299,8 +300,8 @@ org.springframework.scripting.groovy.GroovyMessenger@272961 You use the PropertyPlaceholderConfigurer to - externalize property values from a bean definition into another separate - file in the standard Java Properties format. + externalize property values from a bean definition in a separate + file using the standard Java Properties 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 @@ -314,8 +315,8 @@ org.springframework.scripting.groovy.GroovyMessenger@272961 external Properties file. At runtime, a PropertyPlaceholderConfigurer 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. + to replace are specified as placeholders of the form + ${property-name} which follows the Ant / log4j / JSP EL style. <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations" value="classpath:com/foo/jdbc.properties"/> @@ -332,39 +333,52 @@ org.springframework.scripting.groovy.GroovyMessenger@272961 The actual values come from another file in the standard Java Properties format: - jdbc.driverClassName=org.hsqldb.jdbcDriver + jdbc.driverClassName=org.hsqldb.jdbcDriver jdbc.url=jdbc:hsqldb:hsql://production:9002 jdbc.username=sa jdbc.password=root - 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. + Therefore, the string ${jdbc.username} is replaced + at runtime with the value 'sa', and the same applies for other placeholder + values that match keys in the properties file. The + PropertyPlaceholderConfigurer checks for + placeholders in most properties and attributes of a bean definition. + Furthermore, the placeholder prefix and suffix can be customized. With the context 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 + configuration element. One or more locations can be provided as a comma-separated list in the location attribute. <context:property-placeholder location="classpath:com/foo/jdbc.properties"/> - The PropertyPlaceholderConfigurer does not - look for properties only in the Properties file - you specify, but also checks against the Java + The PropertyPlaceholderConfigurer not only + looks for properties in the Properties file + you specify. By default it also checks against the Java System properties if it cannot find a property - you are trying to use. You can customize this behavior by setting the - systemPropertiesMode property of the configurer. It - has three values that specify configurer behavior: always override, - never override, and override only if the property - is not found in the properties file specified. + in the specified properties files. You can customize this behavior by setting the + systemPropertiesMode property of the configurer with + one of the following three supported integer values: - Consult the Javadoc for the - PropertyPlaceholderConfigurer for more - information. + + + + + never (0): Never check system properties + + + fallback (1): Check system properties if not resolvable in the specified properties files. This is the default. + + + override (2): Check system properties first, before trying the specified properties files. This allows system properties to override any other property source. + + + + + Consult the Javadoc for the PropertyPlaceholderConfigurer + for more information. Class name substitution @@ -407,7 +421,7 @@ jdbc.password=root Note that the bean definition is not aware of being overridden, so it is not immediately obvious from the XML - definition file that the override configurer is used. In case of + definition file that the override configurer is being used. In case of multiple PropertyOverrideConfigurer instances that define different values for the same bean property, the last one wins, due to the overriding mechanism. @@ -421,7 +435,7 @@ jdbc.password=root dataSource.driverClassName=com.mysql.jdbc.Driver dataSource.url=jdbc:mysql:mydb - This example file is usable against a container definition that + This example file can be used with a container definition that contains a bean called dataSource, which has driver and url properties. @@ -438,12 +452,12 @@ dataSource.url=jdbc:mysql:mydb of the foo bean is set to the scalar value 123. - + Specified override values are always literal 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. - + With the context namespace introduced in Spring 2.5, it is possible to configure property overriding with a dedicated @@ -454,11 +468,10 @@ dataSource.url=jdbc:mysql:mydb
- Customizing instantiation logic with the - <interfacename>FactoryBean</interfacename> Interface <literal> - </literal> + Customizing instantiation logic with a + <interfacename>FactoryBean</interfacename> - You implement the + Implement the org.springframework.beans.factory.FactoryBean interface for objects that are themselves factories. @@ -492,7 +505,7 @@ dataSource.url=jdbc:mysql:mydb Class getObjectType(): returns the object type returned by the getObject() method or - null if the type is not known in advance + null if the type is not known in advance. @@ -502,15 +515,15 @@ dataSource.url=jdbc:mysql:mydb interface ship with Spring itself. When you need to ask a container for an actual - FactoryBean instance itself, not the bean - it produces, you preface the bean id with the ampersand symbol - & (without quotes) when calling the + FactoryBean instance itself instead of the bean + it produces, preface the bean's id with the ampersand symbol + (&) when calling the getBean() method of the ApplicationContext. So for a given FactoryBean with an id of myBean, invoking getBean("myBean") on the container returns the product of the - FactoryBean, and invoking + FactoryBean; whereas, invoking getBean("&myBean") returns the FactoryBean instance itself.