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; * } * * - *

Scope, DependsOn, Primary, and Lazy

+ *

Profile, Scope, Lazy, DependsOn, Primary, Order

* - *

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. + * *

{@code @Bean} Methods in {@code @Configuration} Classes

* *

Typically, {@code @Bean} methods are declared within {@code @Configuration} @@ -143,7 +171,7 @@ import org.springframework.core.annotation.AliasFor; * *

Bootstrapping

* - *

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. * *

{@code BeanFactoryPostProcessor}-returning {@code @Bean} methods

diff --git a/spring-core/src/main/java/org/springframework/core/annotation/Order.java b/spring-core/src/main/java/org/springframework/core/annotation/Order.java index 2f0612ef8dc..47b182b1594 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/Order.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/Order.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,21 +27,29 @@ import org.springframework.core.Ordered; /** * {@code @Order} defines the sort order for an annotated component. * - *

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