The Spring container can automatically establish relationships between communicating beans. You can let Spring
automatically resolve collaborating objects (other beans) for your bean by looking at the contents of ApplicationContext
.
Automatic detection and linking has the following advantages:
-
Automatic detection and binding can significantly reduce the number of instructions for specifying properties or constructor arguments (Other mechanisms, such as the bean template, discussed in other sections of this chapter, are also useful in this regard.)
-
Automatic discovery and linking allows you to update your configuration as your objects evolve. For example, if you need to add a dependency to a class, that dependency can be satisfied automatically without having to change the configuration. Thus, automatic discovery and linking can be especially useful during development, but does not preclude the possibility of moving to explicit linking once the code base is stable.
When using XML-based configuration metadata, you can set the autowire mode in the bean definition using the autowire
attribute of the <bean/>
element. The automatic discovery and linking functionality has four
modes. You set automatic discovery and linking for each bean and thus can choose which ones to automatically link.
The following table describes the four automatic discovery and binding modes:
Mode | Explanation |
---|---|
|
(Default) No automatic detection and linking. Bean references must be defined by |
|
Automatic discovery and linking by property name. Spring looks for a bean with the same name as the
property that should be automatically discovered and bound. For example, if a bean definition contains
an instruction to automatically detect and bind by name and a |
|
Allows a property to be automatically discovered and associated if exactly one bean with that property
type exists in the container. If more than one exists, a critical exception is thrown indicating that
the |
|
Similar to |
Using the automatic detection and binding mode byType
or constructor
you can link arrays
and typed collections. In such cases, all candidate components for automatic discovery and binding that are in the
container and match the expected type are provided to satisfy the dependency. You can automatically find and
associate strongly typed Map
instances if the expected key type is String
. The values of
an automatically bound Map
instance consist of all bean instances matching the expected type, and the
Map
instance keys contain the corresponding bean names.
Limitations and disadvantages of automatic detection and linking
Automatic discovery and linking works best when used consistently throughout a project. If automatic discovery and linking is not used at all, it may be difficult for developers to use it to link only one or two bean definitions.
Let's look at the limitations and disadvantages of automatic detection and linking:
-
Explicit dependencies in
property
andconstructor-arg
always override automatic discovery and binding. Simple properties such as primitives,Strings
andClasses
(and arrays of such simple properties) cannot be automatically bound. This limitation is intentional. -
Automatic detection and linking is less accurate than explicit linking. Although, as noted in the previous table, Spring tries not to resort to guesswork in case of ambiguity, which can lead to unexpected results. The relationships between your Spring-managed objects are no longer explicitly documented.
-
Binding information may not be available to tools that can generate documentation from a Spring container.
-
Multiple bean definitions in a container can match the type specified by a setter method or constructor argument for automatic discovery and binding. For arrays, collections, or
Map
instances this is not necessarily a problem. However, for dependencies where a single value is expected, this ambiguity is not arbitrarily resolved. If a unique bean definition is not available, an exception is thrown.
In the latter case, you have several options:
-
Avoid automatic discovery and linking in favor of explicit linking.
-
Avoid auto-discovery and binding for a bean definition by setting its
autowire-candidate
attributes tofalse
-
Designate one bean definition as the candidate primary bean by setting the
primary
attribute of the<bean/>
element totrue
. -
Implement the finer control available with annotation-based configuration.
Excluding a bean from the automatic discovery and linking method
For each bin, you can exclude it from the automatic discovery and linking method. In Spring XML format, set the
autowire-candidate
attribute of the <bean/>
element to false
. The
container will make that particular bean definition unavailable to the auto-discovery and binding framework
(including annotation-style configurations such as @Autowired
).
autowire-candidate
attribute is intended only to affect the
type-based autowire detection and binding method. It does not affect explicit references by name, which are resolved
even if the specified bean is not marked as a candidate component for automatic discovery and linking. As a
consequence, automatic detection and linking by name will nevertheless inject the bean if the name matches.
You can also limit candidate components for automatic discovery and binding based on pattern matching to bean names.
The top-level <bean/>
element accepts one or more patterns in its default-autowire-candidates
attribute. For example, to restrict the auto-discovery and binding candidate status of a bean to any bean whose name
ends with Repository
, substitute the value *Repository
. To pass multiple patterns, specify
them in a comma-separated list. An explicit true
or false
value for the autowire-candidate
attribute in a bean definition always takes precedence. For such beans, pattern matching rules do not apply.
These methods are useful if you have beans that you will never need to inject into other beans through automatic discovery and linking. This does not mean that an excluded bean cannot itself be configured through automatic discovery and binding. Rather, the bean itself is not a candidate component for automatically discovering and linking other beans.