Improve documentation for configuration class 'lite' mode

Overhauled the class-level JavaDoc in @Bean:

 - added h3 headers for greater clarity and readability
 - mentioned 'prototype' semantics for lite mode

Issue: SPR-9401
This commit is contained in:
Sam Brannen
2012-05-16 23:08:06 +02:00
parent cf5d55173b
commit 98050268c5

View File

@@ -26,9 +26,12 @@ import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
/**
* Indicates that a method produces a bean to be managed by the Spring container. The
* names and semantics of the attributes to this annotation are intentionally similar
* to those of the {@code <bean/>} element in the Spring XML schema. For example:
* Indicates that a method produces a bean to be managed by the Spring container.
*
* <p>The names and semantics of the attributes to this annotation are intentionally
* similar to those of the {@code <bean/>} element in the Spring XML schema. For
* example:
*
* <pre class="code">
* &#064;Bean
* public MyBean myBean() {
@@ -36,11 +39,15 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
* return obj;
* }</pre>
*
* <p>While a {@link #name()} attribute is available, the default strategy for determining
* the name of a bean is to use the name of the Bean method. This is convenient and
* intuitive, but if explicit naming is desired, the {@code name()} attribute may be used.
* Also note that {@code name()} accepts an array of Strings. This is in order to allow
* for specifying multiple names (i.e., aliases) for a single bean.
* <h3>Bean Names</h3>
*
* <p>While a {@link #name() name} attribute is available, the default strategy for
* determining the name of a bean is to use the name of the {@code @Bean} method.
* This is convenient and intuitive, but if explicit naming is desired, the
* {@code name} attribute may be used. Also note that {@code name} accepts an array
* of Strings. This is in order to allow for specifying multiple names (i.e., aliases)
* for a single bean.
*
* <pre class="code">
* &#064;Bean(name={"b1","b2"}) // bean available as 'b1' and 'b2', but not 'myBean'
* public MyBean myBean() {
@@ -48,10 +55,13 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
* return obj;
* }</pre>
*
* <h3>Scope, Primary, and Lazy</h3>
*
* <p>Note that the {@code @Bean} annotation does not provide attributes for scope,
* primary or lazy. Rather, it should be used in conjunction with {@link Scope @Scope},
* {@link Primary @Primary}, and {@link Lazy @Lazy} annotations to achieve
* those semantics. For example:
* primary, or lazy. Rather, it should be used in conjunction with {@link Scope @Scope},
* {@link Primary @Primary}, and {@link Lazy @Lazy} annotations to achieve those
* semantics. For example:
*
* <pre class="code">
* &#064;Bean
* &#064;Scope("prototype")
@@ -60,15 +70,18 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
* return obj;
* }</pre>
*
* <h3>{@code @Bean} Methods in {@code @Configuration} Classes</h3>
*
* <p>Typically, {@code @Bean} methods are declared within {@code @Configuration}
* classes. In this case, bean methods may reference other <code>@Bean</code> methods
* on the same class by calling them <i>directly</i>. This ensures that references between
* classes. In this case, bean methods may reference other {@code @Bean} methods
* in the same class by calling them <i>directly</i>. This ensures that references between
* beans are strongly typed and navigable. Such so-called 'inter-bean references' are
* guaranteed to respect scoping and AOP semantics, just like <code>getBean</code> lookups
* guaranteed to respect scoping and AOP semantics, just like <code>getBean()</code> lookups
* would. These are the semantics known from the original 'Spring JavaConfig' project
* which require CGLIB subclassing of each such configuration class at runtime. As a
* consequence, {@code @Configuration} classes and their factory methods must not be
* marked as final or private in this mode. For example:
*
* <pre class="code">
* &#064;Configuration
* public class AppConfig {
@@ -83,13 +96,16 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
* // ...
* }</pre>
*
* <h3>Configuration Class <i>Lite</i> Mode</h3>
*
* <p>{@code @Bean} methods may also be declared within any {@code @Component} class, in
* which case they will get processed in a configuration class <em>'lite'</em> mode in which
* they will simply be called as plain factory methods from the container (similar to
* {@code factory-method} declarations in XML). The containing component classes remain
* unmodified in this case, and there are no unusual constraints for factory methods;
* however, scoping semantics are <b>not</b> respected as described above for inter-bean method
* invocations in this mode. For example:
* {@code factory-method} declarations in XML) but with <b><i>prototype</i></b> semantics.
* The containing component classes remain unmodified in this case, and there are no
* unusual constraints for factory methods; however, scoping semantics are <b>not</b>
* respected as described above for inter-bean method invocations in this mode. For example:
*
* <pre class="code">
* &#064;Component
* public class Calculator {
@@ -103,21 +119,26 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
* }
* }</pre>
*
* <h3>Bootstrapping</h3>
*
* <p>See @{@link Configuration} Javadoc for further details including how to bootstrap
* the container using {@link AnnotationConfigApplicationContext} and friends.
*
* <h3>A note on {@code BeanFactoryPostProcessor}-returning {@code @Bean} methods</h3>
* <h3>{@code BeanFactoryPostProcessor}-returning {@code @Bean} methods</h3>
*
* <p>Special consideration must be taken for {@code @Bean} methods that return Spring
* {@link org.springframework.beans.factory.config.BeanFactoryPostProcessor BeanFactoryPostProcessor}
* ({@code BFPP}) types. Because {@code BFPP} objects must be instantiated very early in the
* container lifecycle, they can interfere with processing of annotations such as {@code @Autowired},
* {@code @Value}, and {@code @PostConstruct} within {@code @Configuration} classes. To avoid these
* lifecycle issues, mark {@code BFPP}-returning {@code @Bean} methods as {@code static}. For example:
*
* <pre class="code">
* &#064;Bean
* public static PropertyPlaceholderConfigurer ppc() {
* // instantiate, configure and return ppc ...
* }</pre>
*
* By marking this method as {@code static}, it can be invoked without causing instantiation of its
* declaring {@code @Configuration} class, thus avoiding the above-mentioned lifecycle conflicts.
* Note however that {@code static} {@code @Bean} methods will not be enhanced for scoping and AOP
@@ -141,7 +162,7 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
* @see org.springframework.beans.factory.annotation.Autowired
* @see org.springframework.beans.factory.annotation.Value
*/
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {
@@ -171,20 +192,24 @@ public @interface Bean {
* application context, for example a {@code close()} method on a JDBC {@code
* DataSource} implementation, or a Hibernate {@code SessionFactory} object.
* The method must have no arguments but may throw any exception.
*
* <p>As a convenience to the user, the container will attempt to infer a destroy
* method against object returned from the {@code @Bean} method. For example, given a
* method against an object returned from the {@code @Bean} method. For example, given a
* {@code @Bean} method returning an Apache Commons DBCP {@code BasicDataSource}, the
* container will notice the {@code close()} method available on that object and
* automatically register it as the {@code destroyMethod}. This 'destroy method
* inference' is currently limited to detecting only public, no-arg methods named
* 'close'. The method may be declared at any level of the inheritance hierarchy, and
* will be detected regardless of the return type of the {@code @Bean} method, i.e.
* detection occurs reflectively against the bean instance itself at creation time.
* 'close'. The method may be declared at any level of the inheritance hierarchy and
* will be detected regardless of the return type of the {@code @Bean} method (i.e.,
* detection occurs reflectively against the bean instance itself at creation time).
*
* <p>To disable destroy method inference for a particular {@code @Bean}, specify an
* empty string as the value, e.g. {@code @Bean(destroyMethod="")}.
*
* <p>Note: Only invoked on beans whose lifecycle is under the full control of the
* factory, which is always the case for singletons but not guaranteed
* for any other scope.
* factory, which is always the case for singletons but not guaranteed for any
* other scope.
*
* @see org.springframework.context.ConfigurableApplicationContext#close()
*/
String destroyMethod() default AbstractBeanDefinition.INFER_METHOD;