Browse Source

Comprehensive documentation on injection point matching

Issue: SPR-16142
pull/1578/merge
Juergen Hoeller 8 years ago
parent
commit
a5da05c3dc
  1. 10
      spring-beans/src/main/java/org/springframework/beans/factory/annotation/Autowired.java
  2. 75
      src/docs/asciidoc/core/core-beans.adoc

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

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -43,9 +43,11 @@ import java.lang.annotation.Target;
* applicable for all arguments. * applicable for all arguments.
* *
* <p>In case of a {@link java.util.Collection} or {@link java.util.Map} * <p>In case of a {@link java.util.Collection} or {@link java.util.Map}
* dependency type, the container will autowire all beans matching the * dependency type, the container can autowire all beans matching the
* declared value type. In case of a Map, the keys must be declared as * declared value type. For such purposes, the map keys must be declared
* type String and will be resolved to the corresponding bean names. * 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.
* *
* <p>Note that actual injection is performed through a * <p>Note that actual injection is performed through a
* {@link org.springframework.beans.factory.config.BeanPostProcessor * {@link org.springframework.beans.factory.config.BeanPostProcessor

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

@ -4211,11 +4211,13 @@ applicability. Spring 2.5 also added support for JSR-250 annotations such as
Injection for Java) annotations contained in the javax.inject package such as `@Inject` Injection for Java) annotations contained in the javax.inject package such as `@Inject`
and `@Named`. Details about those annotations can be found in the and `@Named`. Details about those annotations can be found in the
<<beans-standard-annotations,relevant section>>. <<beans-standard-annotations,relevant section>>.
[NOTE] [NOTE]
==== ====
Annotation injection is performed __before__ XML injection, thus the latter Annotation injection is performed __before__ XML injection, thus the latter
configuration will override the former for properties wired through both approaches. configuration will override the former for properties wired through both approaches.
==== ====
As always, you can register them as individual bean definitions, but they can also be As always, you can register them as individual bean definitions, but they can also be
implicitly registered by including the following tag in an XML-based Spring implicitly registered by including the following tag in an XML-based Spring
configuration (notice the inclusion of the `context` namespace): 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
by the container. If no value is injected, a corresponding exception is raised. by the container. If no value is injected, a corresponding exception is raised.
==== ====
Alternatively, you may express the non-required nature of a particular dependency
through Java 8's `java.util.Optional`:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
public class SimpleMovieLister {
@Autowired
public void setMovieFinder(Optional<MovieFinder> movieFinder) {
...
}
}
----
As of Spring Framework 5.0, you may also use an `@Nullable` annotation (of any kind
in any package, e.g. `javax.annotation.Nullable` from JSR-305):
[source,java,indent=0]
[subs="verbatim,quotes"]
----
public class SimpleMovieLister {
@Autowired
public void setMovieFinder(@Nullable MovieFinder movieFinder) {
...
}
}
----
You can also use `@Autowired` for interfaces that are well-known resolvable You can also use `@Autowired` for interfaces that are well-known resolvable
dependencies: `BeanFactory`, `ApplicationContext`, `Environment`, `ResourceLoader`, dependencies: `BeanFactory`, `ApplicationContext`, `Environment`, `ResourceLoader`,
`ApplicationEventPublisher`, and `MessageSource`. These interfaces and their extended `ApplicationEventPublisher`, and `MessageSource`. These interfaces and their extended
@ -4601,6 +4633,7 @@ The corresponding bean definitions appear as follows.
---- ----
[[beans-autowired-annotation-qualifiers]] [[beans-autowired-annotation-qualifiers]]
=== Fine-tuning annotation-based autowiring with qualifiers === Fine-tuning annotation-based autowiring with qualifiers
@ -4700,9 +4733,16 @@ be injected into a `Set<MovieCatalog>` annotated with `@Qualifier("action")`.
[TIP] [TIP]
==== ====
If you intend to express annotation-driven injection by name, do not primarily use Letting qualifier values select against target bean names, within the type-matching
`@Autowired`, even if is technically capable of referring to a bean name through candidates, doesn't even require a `@Qualifier` annotation at the injection point.
`@Qualifier` values. Instead, use the JSR-250 `@Resource` annotation, which is If there is no other resolution indicator (e.g. a qualifier or a primary marker),
for a non-unique dependency situation, Spring will match the injection point name
(i.e. field name or parameter name) against the target bean names and choose the
same-named candidate, if any.
That said, if you intend to express annotation-driven injection by name, do not
primarily use `@Autowired`, even if is capable of selecting by bean name among
type-matching candidates. Instead, use the JSR-250 `@Resource` annotation, which is
semantically defined to identify a specific target component by its unique name, with semantically defined to identify a specific target component by its unique name, with
the declared type being irrelevant for the matching process. `@Autowired` has rather the declared type being irrelevant for the matching process. `@Autowired` has rather
different semantics: After selecting candidate beans by type, the specified String different semantics: After selecting candidate beans by type, the specified String
@ -4870,7 +4910,6 @@ consider the following annotation definition:
String genre(); String genre();
Format format(); Format format();
} }
---- ----
@ -6006,6 +6045,34 @@ you should use the `@Named` annotation as follows:
} }
---- ----
Like `@Autowired`, `@Inject` can also be used with `java.util.Optional` or
`@Nullable`. This is even more applicable here since `@Inject` does not have
a `required` attribute.
[source,java,indent=0]
[subs="verbatim,quotes"]
----
public class SimpleMovieLister {
@Inject
public void setMovieFinder(Optional<MovieFinder> movieFinder) {
...
}
}
----
[source,java,indent=0]
[subs="verbatim,quotes"]
----
public class SimpleMovieLister {
@Inject
public void setMovieFinder(@Nullable MovieFinder movieFinder) {
...
}
}
----
[[beans-named]] [[beans-named]]

Loading…
Cancel
Save