From 6e20f8d0a560300691f7c15bc05ab2baa397168e Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 17 Jul 2019 18:55:58 +0200 Subject: [PATCH] Improve documentation for @Autowired constructors Prior to this commit, there was some ambiguity surrounding semantics for @Autowired constructors and `required = true`, especially for multiple @Autowired constructors. This commit improves the documentation in the Javadoc for @Autowired as well as in the reference manual. Closes gh-23263 --- .../beans/factory/annotation/Autowired.java | 26 ++++++++++--------- src/asciidoc/core-beans.adoc | 26 ++++++++++++------- 2 files changed, 30 insertions(+), 22 deletions(-) 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 89439f0da4d..29a54c50477 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -23,19 +23,21 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * Marks a constructor, field, setter method or config method as to be autowired by + * Marks a constructor, field, setter method, or config method as to be autowired by * Spring's dependency injection facilities. This is an alternative to the JSR-330 * {@link javax.inject.Inject} annotation, adding required-vs-optional semantics. * - *

Only one constructor (at max) of any given bean class may declare this annotation - * with the 'required' parameter set to {@code true}, indicating the constructor - * to autowire when used as a Spring bean. If multiple non-required constructors - * declare the annotation, they will be considered as candidates for autowiring. - * The constructor with the greatest number of dependencies that can be satisfied by - * matching beans in the Spring container will be chosen. If none of the candidates - * can be satisfied, then a standard default constructor (if present) will be used. - * If a class only declares a single constructor to begin with, it will always be used, - * even if not annotated. An annotated constructor does not have to be public. + *

Only one constructor of any given bean class may declare this annotation with + * the 'required' attribute set to {@code true}, indicating the constructor + * to autowire when used as a Spring bean. Furthermore, if the 'required' attribute + * is set to {@code true}, only a single constructor may be annotated with + * {@code @Autowired}. If multiple non-required constructors declare the + * annotation, they will be considered as candidates for autowiring. The constructor + * with the greatest number of dependencies that can be satisfied by matching beans + * in the Spring container will be chosen. If none of the candidates can be satisfied, + * then a primary/default constructor (if present) will be used. If a class only + * declares a single constructor to begin with, it will always be used, even if not + * annotated. An annotated 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. @@ -45,7 +47,7 @@ import java.lang.annotation.Target; * 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 a multi-arg constructor or method, the 'required' parameter is + *

In the case of a multi-arg constructor or method, the 'required' attribute is * applicable to all arguments. Individual parameters may be declared as Java-8-style * {@link java.util.Optional}, overriding the base required semantics. * diff --git a/src/asciidoc/core-beans.adoc b/src/asciidoc/core-beans.adoc index 6ca037e5f40..cee75be0175 100644 --- a/src/asciidoc/core-beans.adoc +++ b/src/asciidoc/core-beans.adoc @@ -4530,16 +4530,22 @@ indicating __required__ dependencies. This behavior can be changed as demonstrat [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 -satisfied, that is the constructor that has the largest number of arguments. - -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. +Only one constructor of any given bean class may declare `@Autowired` with the `required` +attribute set to `true`, indicating _the_ constructor to autowire when used as a Spring +bean. Furthermore, if the `required` attribute is set to `true`, only a single +constructor may be annotated with `@Autowired`. If multiple _non-required_ constructors +declare the annotation, they will be considered as candidates for autowiring. The +constructor with the greatest number of dependencies that can be satisfied by matching +beans in the Spring container will be chosen. If none of the candidates can be satisfied, +then a primary/default constructor (if present) will be used. If a class only declares a +single constructor to begin with, it will always be used, even if not annotated. An +annotated constructor does not have to be public. + +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 may express the non-required nature of a particular dependency