Skip to content

Commit a5da05c

Browse files
committed
Comprehensive documentation on injection point matching
Issue: SPR-16142
1 parent 423af67 commit a5da05c

File tree

2 files changed

+77
-8
lines changed

2 files changed

+77
-8
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/annotation/Autowired.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -43,9 +43,11 @@
4343
* applicable for all arguments.
4444
*
4545
* <p>In case of a {@link java.util.Collection} or {@link java.util.Map}
46-
* dependency type, the container will autowire all beans matching the
47-
* declared value type. In case of a Map, the keys must be declared as
48-
* type String and will be resolved to the corresponding bean names.
46+
* dependency type, the container can autowire all beans matching the
47+
* declared value type. For such purposes, the map keys must be declared
48+
* as type String and will be resolved to the corresponding bean names.
49+
* Alternatively, a target bean may also be of type {@code Collection} or
50+
* {@code Map} itself, getting injected as such.
4951
*
5052
* <p>Note that actual injection is performed through a
5153
* {@link org.springframework.beans.factory.config.BeanPostProcessor

src/docs/asciidoc/core/core-beans.adoc

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4211,11 +4211,13 @@ applicability. Spring 2.5 also added support for JSR-250 annotations such as
42114211
Injection for Java) annotations contained in the javax.inject package such as `@Inject`
42124212
and `@Named`. Details about those annotations can be found in the
42134213
<<beans-standard-annotations,relevant section>>.
4214+
42144215
[NOTE]
42154216
====
42164217
Annotation injection is performed __before__ XML injection, thus the latter
42174218
configuration will override the former for properties wired through both approaches.
42184219
====
4220+
42194221
As always, you can register them as individual bean definitions, but they can also be
42204222
implicitly registered by including the following tag in an XML-based Spring
42214223
configuration (notice the inclusion of the `context` namespace):
@@ -4494,6 +4496,36 @@ hand, is stronger in that it enforces the property that was set by any means sup
44944496
by the container. If no value is injected, a corresponding exception is raised.
44954497
====
44964498

4499+
Alternatively, you may express the non-required nature of a particular dependency
4500+
through Java 8's `java.util.Optional`:
4501+
4502+
[source,java,indent=0]
4503+
[subs="verbatim,quotes"]
4504+
----
4505+
public class SimpleMovieLister {
4506+
4507+
@Autowired
4508+
public void setMovieFinder(Optional<MovieFinder> movieFinder) {
4509+
...
4510+
}
4511+
}
4512+
----
4513+
4514+
As of Spring Framework 5.0, you may also use an `@Nullable` annotation (of any kind
4515+
in any package, e.g. `javax.annotation.Nullable` from JSR-305):
4516+
4517+
[source,java,indent=0]
4518+
[subs="verbatim,quotes"]
4519+
----
4520+
public class SimpleMovieLister {
4521+
4522+
@Autowired
4523+
public void setMovieFinder(@Nullable MovieFinder movieFinder) {
4524+
...
4525+
}
4526+
}
4527+
----
4528+
44974529
You can also use `@Autowired` for interfaces that are well-known resolvable
44984530
dependencies: `BeanFactory`, `ApplicationContext`, `Environment`, `ResourceLoader`,
44994531
`ApplicationEventPublisher`, and `MessageSource`. These interfaces and their extended
@@ -4601,6 +4633,7 @@ The corresponding bean definitions appear as follows.
46014633
----
46024634

46034635

4636+
46044637
[[beans-autowired-annotation-qualifiers]]
46054638
=== Fine-tuning annotation-based autowiring with qualifiers
46064639

@@ -4700,9 +4733,16 @@ be injected into a `Set<MovieCatalog>` annotated with `@Qualifier("action")`.
47004733

47014734
[TIP]
47024735
====
4703-
If you intend to express annotation-driven injection by name, do not primarily use
4704-
`@Autowired`, even if is technically capable of referring to a bean name through
4705-
`@Qualifier` values. Instead, use the JSR-250 `@Resource` annotation, which is
4736+
Letting qualifier values select against target bean names, within the type-matching
4737+
candidates, doesn't even require a `@Qualifier` annotation at the injection point.
4738+
If there is no other resolution indicator (e.g. a qualifier or a primary marker),
4739+
for a non-unique dependency situation, Spring will match the injection point name
4740+
(i.e. field name or parameter name) against the target bean names and choose the
4741+
same-named candidate, if any.
4742+
4743+
That said, if you intend to express annotation-driven injection by name, do not
4744+
primarily use `@Autowired`, even if is capable of selecting by bean name among
4745+
type-matching candidates. Instead, use the JSR-250 `@Resource` annotation, which is
47064746
semantically defined to identify a specific target component by its unique name, with
47074747
the declared type being irrelevant for the matching process. `@Autowired` has rather
47084748
different semantics: After selecting candidate beans by type, the specified String
@@ -4870,7 +4910,6 @@ consider the following annotation definition:
48704910
String genre();
48714911
48724912
Format format();
4873-
48744913
}
48754914
----
48764915

@@ -6006,6 +6045,34 @@ you should use the `@Named` annotation as follows:
60066045
}
60076046
----
60086047

6048+
Like `@Autowired`, `@Inject` can also be used with `java.util.Optional` or
6049+
`@Nullable`. This is even more applicable here since `@Inject` does not have
6050+
a `required` attribute.
6051+
6052+
[source,java,indent=0]
6053+
[subs="verbatim,quotes"]
6054+
----
6055+
public class SimpleMovieLister {
6056+
6057+
@Inject
6058+
public void setMovieFinder(Optional<MovieFinder> movieFinder) {
6059+
...
6060+
}
6061+
}
6062+
----
6063+
6064+
[source,java,indent=0]
6065+
[subs="verbatim,quotes"]
6066+
----
6067+
public class SimpleMovieLister {
6068+
6069+
@Inject
6070+
public void setMovieFinder(@Nullable MovieFinder movieFinder) {
6071+
...
6072+
}
6073+
}
6074+
----
6075+
60096076

60106077

60116078
[[beans-named]]

0 commit comments

Comments
 (0)