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:

Table 2. Automatic detection and linking modes
Mode Explanation

no

(Default) No automatic detection and linking. Bean references must be defined by ref elements. Changing the default setting is not recommended for large deployments because explicitly specifying interacting objects provides greater control and clarity. To some extent, it documents the structure of the system.

byName

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 master property (that is, it has a setMaster(..) method), Spring looks for a bean definition with the name master and uses it to set the property.

byType

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 byType auto-detection and binding mode cannot be used for that bean. If there are no matching beans, nothing will happen (the property will not be set).

constructor

Similar to byType, but applies to constructor arguments. If the container does not have exactly one bean with the constructor argument type, then a critical error occurs.

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 and constructor-arg always override automatic discovery and binding. Simple properties such as primitives, Strings and Classes (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 to false

  • Designate one bean definition as the candidate primary bean by setting the primary attribute of the <bean/> element to true.

  • 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).

The 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.