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:
@@ -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">
|
||||
* @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">
|
||||
* @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">
|
||||
* @Bean
|
||||
* @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">
|
||||
* @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">
|
||||
* @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">
|
||||
* @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;
|
||||
|
||||
Reference in New Issue
Block a user