From 97b83a3e4a16488438b9183760f7f1e0f778b88a Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 4 Apr 2019 16:09:51 +0200 Subject: [PATCH] Revised documentation on constructor autowiring semantics Closes gh-22735 --- src/docs/asciidoc/core/core-beans.adoc | 54 ++++++++++++++++++-------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/src/docs/asciidoc/core/core-beans.adoc b/src/docs/asciidoc/core/core-beans.adoc index 5e77405f70..40dde2635c 100644 --- a/src/docs/asciidoc/core/core-beans.adoc +++ b/src/docs/asciidoc/core/core-beans.adoc @@ -4690,9 +4690,9 @@ implementation type, consider declaring the most specific return type on your fa method (at least as specific as required by the injection points referring to your bean). ==== -You can also provide all beans of a particular type from the -`ApplicationContext` by adding the annotation to a field or method that expects an array -of that type, as the following example shows: +You can also provide all beans of a particular type from the `ApplicationContext` +by adding the annotation to a field or method that expects an array of that type, +as the following example shows: ==== [source,java,indent=0] @@ -4746,8 +4746,8 @@ Note that the standard `javax.annotation.Priority` annotation is not available a through `@Order` values in combination with `@Primary` on a single bean for each type. ==== -Even typed `Map` instances can be autowired as long as the expected key type is `String`. The Map -values contain all beans of the expected type, and the keys contain the +Even typed `Map` instances can be autowired as long as the expected key type is `String`. +The Map values contain all beans of the expected type, and the keys contain the corresponding bean names, as the following example shows: ==== @@ -4768,10 +4768,14 @@ corresponding bean names, as the following example shows: ---- ==== -By default, the autowiring fails whenever zero candidate beans are available. The -default behavior is to treat annotated methods, constructors, and fields as -indicating required dependencies. You can change this behavior as demonstrated, in the -following example: +By default, autowiring fails when no matching candidate beans are available for +a given injection point. In the case of a declared array, collection or map, +at least one matching element is expected. + +The default behavior is to treat annotated methods and fields as indicating +required dependencies. You can change this behavior as demonstrated in the +following example, enabling the framework to skip a non-satisfiable injection +point through marking it as non-required: ==== [source,java,indent=0] @@ -4791,18 +4795,34 @@ following example: ---- ==== +A non-required method will not be called at all if its dependency (or one of its +dependencies in case of multiple arguments) is not available. A non-required field +will not get populated at all in such case, leaving its default value in place. + +Injected constructor and factory method arguments are a special case since the +'required' flag on `@Autowired` has a somewhat different meaning due to Spring's +constructor resolution algorithm potentially dealing with multiple constructors. +Constructor and factory method arguments are effectively required by default but +with a few special rules in a single-constructor scenario, such as multi-element +injection points (arrays, collections, maps) resolving to empty instances if no +matching beans are available. This allows for a common implementation pattern +where all dependencies can be declared in a unique multi-argument constructor, +e.g. declared as a single public constructor without an `@Autowired` annotation. + [NOTE] ==== -Only one annotated constructor per-class can be marked as required, but multiple -non-required constructors can be annotated. In that case, each is considered among the -candidates and Spring uses the greediest constructor whose dependencies can be +Only one annotated constructor per class can be marked as required, but multiple +non-required constructors can be annotated. In that case, each is considered among +the candidates and Spring uses the greediest constructor whose dependencies can be satisfied -- that is, the constructor that has the largest number of arguments. +The constructor resolution algorithm is the same as for non-annotated classes with +overloaded constructors, just narrowing the candidates to annotated constructors. -The required attribute of `@Autowired` is recommended over the `@Required` annotation. -The required attribute indicates that the property is not required for autowiring -purposes. The property is ignored if it cannot be autowired. `@Required`, on the other -hand, is stronger in that it enforces the property that was set by any means supported -by the container. If no value is injected, a corresponding exception is raised. +The 'required' attribute of `@Autowired` is recommended over the `@Required` annotation +on setter methods. The 'required' attribute indicates that the property is not required +for autowiring purposes. The property is ignored if it cannot be autowired. `@Required`, +on the other hand, is stronger in that it enforces the property to be set by any means +supported by the container. If no value is defined, a corresponding exception is raised. ==== Alternatively, you can express the non-required nature of a particular dependency