diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/Autowired.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/Autowired.java index de2ae4f9376..cfc5d9d4c41 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/Autowired.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/Autowired.java @@ -23,31 +23,34 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * Marks a constructor, field, setter method or config method as to be - * autowired by Spring's dependency injection facilities. + * Marks a constructor, field, setter method or config method as to be autowired + * by Spring's dependency injection facilities. * - *
Only one constructor (at max) of any given bean class may carry this - * annotation, indicating the constructor to autowire when used as a Spring - * bean. Such a constructor does not have to be public. + *
Only one constructor (at max) of any given bean class may carry this annotation, + * indicating the constructor to autowire when used as a Spring bean. Such a + * constructor does not have to be public. * - *
Fields are injected right after construction of a bean, before any - * config methods are invoked. Such a config field does not have to be public. + *
Fields are injected right after construction of a bean, before any config + * methods are invoked. Such a config field does not have to be public. * - *
Config methods may have an arbitrary name and any number of arguments; - * each of those arguments will be autowired with a matching bean in the - * Spring container. Bean property setter methods are effectively just - * a special case of such a general config method. Such config methods - * do not have to be public. + *
Config methods may have an arbitrary name and any number of arguments; each of + * those arguments will be autowired with a matching bean in the Spring container. + * Bean property setter methods are effectively just a special case of such a general + * config method. Such config methods do not have to be public. * - *
In the case of multiple argument methods, the 'required' parameter is - * applicable for all arguments. + *
In the case of a multi-arg constructor or method, the 'required' parameter is + * applicable to all arguments. Individual parameters may be declared as Java-8-style + * {@link java.util.Optional} or, as of Spring Framework 5.0, also as {@code @Nullable} + * or a not-null parameter type in Kotlin, overriding the base required semantics. * - *
In case of a {@link java.util.Collection} or {@link java.util.Map} - * dependency type, the container can autowire all beans matching the - * declared value type. For such purposes, the map keys must be declared - * as type String and will be resolved to the corresponding bean names. - * Alternatively, a target bean may also be of type {@code Collection} or - * {@code Map} itself, getting injected as such. + *
In case of a {@link java.util.Collection} or {@link java.util.Map} dependency type, + * the container autowires all beans matching the declared value type. For such purposes, + * the map keys must be declared as type String which will be resolved to the corresponding + * bean names. Such a container-provided collection will be ordered, taking into account + * {@link org.springframework.core.Ordered}/{@link org.springframework.core.annotation.Order} + * values of the target components, otherwise following their registration order in the + * container. Alternatively, a single matching target bean may also be a generally typed + * {@code Collection} or {@code Map} itself, getting injected as such. * *
Note that actual injection is performed through a * {@link org.springframework.beans.factory.config.BeanPostProcessor diff --git a/spring-context/src/main/java/org/springframework/context/annotation/Bean.java b/spring-context/src/main/java/org/springframework/context/annotation/Bean.java index 4d82f5d17cf..cc57a06845d 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/Bean.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/Bean.java @@ -60,15 +60,16 @@ import org.springframework.core.annotation.AliasFor; * } * * - *
Note that the {@code @Bean} annotation does not provide attributes for scope, - * depends-on, primary, or lazy. Rather, it should be used in conjunction with - * {@link Scope @Scope}, {@link DependsOn @DependsOn}, {@link Primary @Primary}, - * and {@link Lazy @Lazy} annotations to achieve those semantics. For example: + *
Note that the {@code @Bean} annotation does not provide attributes for profile, + * scope, lazy, depends-on or primary. Rather, it should be used in conjunction with + * {@link Scope @Scope}, {@link Lazy @Lazy}, {@link DependsOn @DependsOn} and + * {@link Primary @Primary} annotations to declare those semantics. For example: * *
* @Bean
+ * @Profile("production")
* @Scope("prototype")
* public MyBean myBean() {
* // instantiate and configure MyBean obj
@@ -76,6 +77,33 @@ import org.springframework.core.annotation.AliasFor;
* }
*
*
+ * The semantics of the above-mentioned annotations match their use at the component
+ * class level: {@code Profile} allows for selective inclusion of certain beans.
+ * {@code @Scope} changes the bean's scope from singleton to the specified scope.
+ * {@code @Lazy} only has an actual effect in case of the default singleton scope.
+ * {@code @DependsOn} enforces the creation of specific other beans before this
+ * bean will be created, in addition to any dependencies that the bean expressed
+ * through direct references, which is typically helpful for singleton startup.
+ * {@code @Primary} is a mechanism to resolve ambiguity at the injection point level
+ * if a single target component needs to be injected but several beans match by type.
+ *
+ * Additionally, {@code @Bean} methods may also declare qualifier annotations + * and {@link org.springframework.core.annotation.Order @Order} values, to be + * taken into account during injection point resolution just like corresponding + * annotations on the corresponding component classes but potentially being very + * individual per bean definition (in case of multiple definitions with the same + * bean class). Qualifiers narrow the set of candidates after the initial type match; + * order values determine the order of resolved elements in case of collection + * injection points (with several target beans matching by type and qualifier). + * + *
NOTE: {@code @Order} values may influence priorities at injection points + * but please be aware that they do not influence singleton startup order which is an + * orthogonal concern determined by dependency relationships and {@code @DependsOn} + * declarations as mentioned above. Also, {@link javax.annotation.Priority} is not + * available at this level since it cannot be declared on methods; its semantics can + * be modelled through {@code @Order} values in combination with {@code @Primary} on + * a single bean per type. + * *
Typically, {@code @Bean} methods are declared within {@code @Configuration} @@ -143,7 +171,7 @@ import org.springframework.core.annotation.AliasFor; * *
See @{@link Configuration} Javadoc for further details including how to bootstrap + *
See the @{@link Configuration} javadoc for further details including how to bootstrap * the container using {@link AnnotationConfigApplicationContext} and friends. * *
The {@link #value} is optional and represents an order value as defined - * in the {@link Ordered} interface. Lower values have higher priority. The - * default value is {@code Ordered.LOWEST_PRECEDENCE}, indicating - * lowest priority (losing to any other specified order value). + *
The {@link #value} is optional and represents an order value as defined in the + * {@link Ordered} interface. Lower values have higher priority. The default value is + * {@code Ordered.LOWEST_PRECEDENCE}, indicating lowest priority (losing to any other + * specified order value). * - *
Since Spring 4.1, the standard {@link javax.annotation.Priority} - * annotation can be used as a drop-in replacement for this annotation. + *
NOTE: Since Spring 4.0, annotation-based ordering is supported for many + * kinds of components in Spring, even for collection injection where the order values + * of the target components are taken into account (either from their target class or + * from their {@code @Bean} method). While such order values may influence priorities + * at injection points, please be aware that they do not influence singleton startup + * order which is an orthogonal concern determined by dependency relationships and + * {@code @DependsOn} declarations (influencing a runtime-determined dependency graph). * - *
NOTE: Annotation-based ordering is supported for specific kinds - * of components only — for example, for annotation-based AspectJ - * aspects. Ordering strategies within the Spring container, on the other - * hand, are typically based on the {@link Ordered} interface in order to - * allow for programmatically configurable ordering of each instance. + *
Since Spring 4.1, the standard {@link javax.annotation.Priority} annotation + * can be used as a drop-in replacement for this annotation in ordering scenarios. + * Note that {@code Priority} may have additional semantics when a single element + * has to be picked (see {@link AnnotationAwareOrderComparator#getPriority}). * - *
Consult the Javadoc for {@link org.springframework.core.OrderComparator + *
Alternatively, order values may also be determined on a per-instance basis + * through the {@link Ordered} interface, allowing for configuration-determined + * instance values instead of hard-coded values attached to a particular class. + * + *
Consult the javadoc for {@link org.springframework.core.OrderComparator * OrderComparator} for details on the sort semantics for non-ordered objects. * * @author Rod Johnson diff --git a/src/docs/asciidoc/core/core-beans.adoc b/src/docs/asciidoc/core/core-beans.adoc index a8f735ef24b..3560ac7279b 100644 --- a/src/docs/asciidoc/core/core-beans.adoc +++ b/src/docs/asciidoc/core/core-beans.adoc @@ -4437,9 +4437,20 @@ The same applies for typed collections: [TIP] ==== -Your beans can implement the `org.springframework.core.Ordered` interface or either use +Your target beans can implement the `org.springframework.core.Ordered` interface or use the `@Order` or standard `@Priority` annotation if you want items in the array or list -to be sorted into a specific order. +to be sorted into a specific order. Otherwise their order will follow the registration +order of the corresponding target bean definitions in the container. + +The `@Order` annotation may be declared at target class level but also on `@Bean` methods, +potentially being very individual per bean definition (in case of multiple definitions +with the same bean class). `@Order` values may influence priorities at injection points +but please be aware that they do not influence singleton startup order which is an +orthogonal concern determined by dependency relationships and `@DependsOn` declarations. + +Note that the standard `javax.annotation.Priority` annotation is not available at the +`@Bean` level since it cannot be declared on methods. Its semantics can be modelled +through `@Order` values in combination with `@Primary` on a single bean per type. ==== Even typed Maps can be autowired as long as the expected key type is `String`. The Map @@ -7004,7 +7015,6 @@ another configuration class: public A a() { return new A(); } - } @Configuration @@ -7267,6 +7277,14 @@ way, navigating `@Configuration` classes and their dependencies becomes no diffe than the usual process of navigating interface-based code. -- +[TIP] +==== +If you would like to influence the startup creation order of certain beans, consider +declaring some of them as `@Lazy` (for creation on first access instead of on startup) +or as `@DependsOn` on certain other beans (making sure that specific other beans will +be created before the current bean, beyond what the latter's direct dependencies imply). +==== + [[beans-java-conditional]] ==== Conditionally include @Configuration classes or @Bean methods