class MovieRecommender @Autowired constructor(
private val customerPreferenceDao: CustomerPreferenceDao) {
@Autowired
private lateinit var movieCatalog: MovieCatalog
// ...
Make sure that your target components (for example, MovieCatalog
or CustomerPreferenceDao
)
are consistently declared by the type that you use for your @Autowired
-annotated
injection points. Otherwise, injection may fail due to a "no type match found" error at runtime.
For XML-defined beans or component classes found via classpath scanning, the container
usually knows the concrete type up front. However, for @Bean
factory methods, you need
to make sure that the declared return type is sufficiently expressive. For components
that implement several interfaces or for components potentially referred to by their
implementation type, consider declaring the most specific return type on your factory
method (at least as specific as required by the injection points referring to your bean).
As of 4.3, @Autowired
also considers self references for injection (that is, references
back to the bean that is currently injected). Note that self injection is a fallback.
In practice, you should use self references as a last resort only (for example, for
calling other methods on the same instance through the bean’s transactional proxy).
Consider factoring out the affected methods to a separate delegate bean in such a scenario.
You can also instruct Spring to provide all beans of a particular type from the
ApplicationContext
by adding the @Autowired
annotation to a field or method that
expects an array of that type, as the following example shows:
@Autowired
public void setMovieCatalogs(Set<MovieCatalog> movieCatalogs) {
this.movieCatalogs = movieCatalogs;
// ...
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 in a specific order. Otherwise, their order follows the registration
order of the corresponding target bean definitions in the container.
You can declare the @Order
annotation at the target class level and on @Bean
methods,
potentially for individual bean definitions (in case of multiple definitions that
use the same bean class). @Order
values may influence priorities at injection points,
but be aware that they do not influence singleton startup order, which is an
orthogonal concern determined by dependency relationships and @DependsOn
declarations.
Note that @Order
annotations on configuration classes just influence the evaluation
order within the overall set of configuration classes on startup. Such configuration-level
order values do not affect the contained @Bean
methods at all. For bean-level ordering,
each @Bean
method needs to have its own @Order
annotation which applies within a
set of multiple matches for the specific bean type (as returned by the factory method).
Note that the standard jakarta.annotation.Priority
annotation is not available at the
@Bean
level, since it cannot be declared on methods. Its semantics can be modeled
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
corresponding bean names, as the following example shows:
@Autowired
public void setMovieCatalogs(Map<String, MovieCatalog> movieCatalogs) {
this.movieCatalogs = movieCatalogs;
// ...
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 (i.e., by setting the required
attribute in @Autowired
to false
):
@Autowired(required = false)
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
// ...
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 cases, leaving its default value in place.
In other words, setting the required
attribute to false
indicates that the
corresponding property is optional for autowiring purposes, and the property will be
ignored if it cannot be autowired. This allows properties to be assigned default values
that can be optionally overridden via dependency injection.
Injected constructor and factory method arguments are a special case since the required
attribute in @Autowired
has a somewhat different meaning due to Spring’s constructor
resolution algorithm that may potentially deal 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 — for example, declared as a single public constructor
without an @Autowired
annotation.
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. As a consequence, if the required
attribute is left at its default value true
,
only a single constructor may be annotated with @Autowired
. If multiple constructors
declare the annotation, they will all have to declare required=false
in order to be
considered as candidates for autowiring (analogous to autowire=constructor
in XML).
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. Similarly, if a class
declares multiple constructors but none of them is annotated with @Autowired
, 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. Note that an
annotated constructor does not have to be public.
As of Spring Framework 5.0, you can also use a @Nullable
annotation (of any kind
in any package — for example, javax.annotation.Nullable
from JSR-305) or just leverage
Kotlin built-in null-safety support:
You can also use @Autowired
for interfaces that are well-known resolvable
dependencies: BeanFactory
, ApplicationContext
, Environment
, ResourceLoader
,
ApplicationEventPublisher
, and MessageSource
. These interfaces and their extended
interfaces, such as ConfigurableApplicationContext
or ResourcePatternResolver
, are
automatically resolved, with no special setup necessary. The following example autowires
an ApplicationContext
object:
The @Autowired
, @Inject
, @Value
, and @Resource
annotations are handled by Spring
BeanPostProcessor
implementations. This means that you cannot apply these annotations
within your own BeanPostProcessor
or BeanFactoryPostProcessor
types (if any).
These types must be 'wired up' explicitly by using XML or a Spring @Bean
method.
Apache®, Apache Tomcat®, Apache Kafka®, Apache Cassandra™, and Apache Geode™ are trademarks or registered trademarks of the Apache Software Foundation in the United States and/or other countries. Java™, Java™ SE, Java™ EE, and OpenJDK™ are trademarks of Oracle and/or its affiliates. Kubernetes® is a registered trademark of the Linux Foundation in the United States and other countries. Linux® is the registered trademark of Linus Torvalds in the United States and other countries. Windows® and Microsoft® Azure are registered trademarks of Microsoft Corporation. “AWS” and “Amazon Web Services” are trademarks or registered trademarks of Amazon.com Inc. or its affiliates. All other trademarks and copyrights are property of their respective owners and are only mentioned for informative purposes. Other names may be trademarks of their respective owners.