3.10 Autowiring

Typically setting bean dependencies explicitly is a good practice to follow, but Spring can also automatically resolve dependencies. This automatic resolution of bean dependencies is also called autowiring. These bean dependencies can also be referred to as collaborating beans or just as collaborators. The 5 different types of autowiring are 'no', 'byName', 'byType', 'constructor', and 'autodetect'. Autowiring is turned off by default, so the default autowiring mode for a bean is 'no'. Also, any constructor argument or property explicitly set will not be eligible for autowiring.

Table 3.2. Autowiring Types

Autowiring ModeDescription
noNo autowiring is performed. All references to other beans must be explicitly injected. This is the default mode.
byNameBased on the name of a property, a matching bean name in the IoC container will be injected into this property if it exists.
byType Based on the type of class on a setter, if only one instance of the class exists in the IoC container it will be injected into this property. If there is more than one instance of the class a fatal exception is thrown.
constructorBased on a constructor argument's class types, if only one instance of the class exists in the IoC container it will be used in the constructor.
autodetect If there is a valid constructor, the constructor autowiring mode will be chosen. Otherwise if there is a default zero argument constructor the byType autowiring mode will be chosen.


The autowiring 'byName' mode matches a property name to a bean name in the IoC container. For example a property of setHibernateTemplate(HibernateTemplate template) has a property name of 'hibernateTemplate'. So if a hibernateTemplate bean is found it will automatically be injected during the autowiring process.

When using the 'byType' autowiring mode the class of a setter will be used to find a bean. If there is more than one class found, a fatal exception is thrown. If there isn't a matching class in the IoC container, nothing will be set and there won't be an exception during processing. If this is undesirable behavior, the bean element's dependency-check attribute can be set to 'object'. Then an error will occur if there isn't a matching class for the property during the autowire process.

The 'constructor' autowiring mode is similar to the 'byType' autowiring mode, but it's for constructors. The constructor with the most parameters that can successfully be autowired will be chosen. There can only be one bean definition for a type to be autowired successfully. If one constructor takes a Person class and the other takes an Address class, then if there are two Address bean definitions and only one bean definition for a Person the constructor that takes the Person class will be used to instantiate the bean. If there is a no parameter constructor, this will be used rather than throw an exception. If there isn't an eligible constructor, a fatal exception will be thrown.

The root beans element has a default-autowire attribute. This can be used to override the default autowiring mode for all beans in the configuration file. This can be used if you want all beans to participate in autowiring. Each bean also has an autowire-candidate attribute that defaults to true. To have it excluded from the container's autowiring default it can be set to false.

Spring recommends not using autowiring for large configurations since it can become confusing what is being set on a bean. Bean inheritance is a good alternative to autowiring since it reduces repetitive injections, but it's still very clear in the configuration what's happening. Autowiring is very powerful, but should be used with caution since it's possible for a property to be set that wasn't intended to be set as development continues.

Example 3.40. XML Autowiring

The following excerpt from the XML configuration file shows a bean being autowired by name, type, and constructor.

Excerpt from chapter03-autowire/src/main/resources/applicationContext.xml
                
    <!-- 
        The 'person' bean is autowired to the Person setter.
    -->
    <bean id="personSetterByName"
          class="org.springbyexample.springindepth.chapter03.autowire.PersonContainer" 
          autowire="byName" />

...
          
    <!-- 
        The 'person' bean is autowired to the Person setter.
    -->
    <bean id="personSetterByType"
          class="org.springbyexample.springindepth.chapter03.autowire.PersonContainer" 
          autowire="byType" />

...

    <!-- 
        The 'person' bean is autowired to the Person constructor.
    -->
    <bean id="personConstructor"
          class="org.springbyexample.springindepth.chapter03.autowire.PersonContainer" 
          autowire="constructor" />
                
            

Annotation-based Configuration

New Feature in Spring 2.5

Support for autowiring with annotations was added in Spring 2.5. The @Autowired annotation can autowire fields, properties, and constructors by type. Arrays, collections, and Java 5 typed collections can also be autowired. All beans of the type that matches the array or collection will be set. To autowire by name, the JSR-250 annotation @Resource can be used or Spring's @Qualifier annotation. Autowiring using annotations will be covered in more detail in the following chapter on annotation-based configuration.

Example 3.41. Annotation-based Autowiring

The following examples show autowiring a constructor and setter by type, and also a setter by name. The person and address beans being autowired are defined in the XML configuration for this example.

Excerpt from chapter03-autowire/src/main/java/org/springbyexample/springindepth/chapter03/autowire/context/PersonConstructorByTypeContainer.java
                    
/**
 * Constructor
 */
@Autowired
public PersonConstructorByTypeContainer(Person person) {
    this.person = person;
    
    logger.debug("Person set on constructor.");
}
                    
                
Excerpt from chapter03-autowire/src/main/java/org/springbyexample/springindepth/chapter03/autowire/context/PersonSetterByTypeContainer.java
                    
/**
 * Sets person.
 */
@Override
@Autowired
public void setPerson(Person person) {
    this.person = person;
    
    logger.debug("Person set on setter.");
}
                    
                
Excerpt from chapter03-autowire/src/main/java/org/springbyexample/springindepth/chapter03/autowire/context/PersonSetterByNameContainer.java
                    
/**
 * Sets person.
 */
@Override
@Resource(name="person")
public void setPerson(Person person) {
    this.person = person;
    
    logger.debug("Person set on setter.");
}
                    
                

The following configuration uses the context:annotation-config element to auto-configure the default annotation-based bean post processors. One of the post processors is the annotation autowiring post processor. The context:component-scan element scans the package that contains the classes configured with annotations and registers them with the IoC container.

Excerpt from chapter03-autowire/src/main/resources/context-applicationContext.xml
                    
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:context="http://www.springframework.org/schema/context"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context.xsd">
    
    <!-- Register Annotation-based Post Processing Beans -->
    <context:annotation-config />
               
    <!-- Scan context package for any eligible annotation configured beans. -->
    <context:component-scan base-package="org.springbyexample.springindepth.chapter03.autowire.context" />

...
    
</beans>