Spring Autowire By Constructor

This tutorial shows how to use spring autowire by constructor. When the autowire by constructor is enabled -which is actually analogous to autowire by type, but applies to constructor arguments- spring will autowire a property if exactly one bean of the property type exists in the container. If there are multiple beans of the same type, a NoUniqueBeanDefinitionException exception will be thrown. If there are no matching beans, nothing happens and the property will not be initialized.

Beans to be autowired

We have two beans Person and Job. Note that the Person bean has a property of Job, we are going to autowire this property by constructor.

package com.memorynotfound.spring.core.autowired;

public class Person {

    private Job job;

    public Person(Job job) {
        this.job = job;
    }

    @Override
    public String toString() {
        return "Person{" +
                "job=" + job +
                '}';
    }
}

This Job bean will be autowired into the Person bean.

package com.memorynotfound.spring.core.autowired;

public class Job {

    private String name;

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Job{" +
                "name='" + name + '\'' +
                '}';
    }
}

Spring Explicit Wiring

You can wire the bean explicitly using the <constructor-arg/> element given a name of the property and a ref attribute that references the bean to be wired.

<bean class="com.memorynotfound.spring.core.autowired.Person">
    <constructor-arg name="job" ref="job"/>
</bean>
<bean id="job" class="com.memorynotfound.spring.core.autowired.Job" >
    <property name="name" value="Java Developer"/>
</bean>

Output

This will produce the following output if we call the toString method of the Person bean.

Person{job=Job{name='Java Developer'}}

Spring Autowire By Constructor

With spring autowire by constructor enabled, the wiring is done implicitly. Which means that you no longer need to explicitly wire the beans together by providing the <constructor-arg/> element of the bean. The wiring is done by constructor, which means that if a matching type is discovered in the container, the autowiring is done implicit.

<bean class="com.memorynotfound.spring.core.autowired.Person" autowire="constructor"/>
<bean class="com.memorynotfound.spring.core.autowired.Job" >
    <property name="name" value="Java Developer"/>
</bean>

Output

This will produce the following output if we call the toString method of the Person bean.

Person{job=Job{name='Java Developer'}}

Spring Autowire by constructor – multiple candidates

With spring autowire by constructor enabled and there are multiple candidates, the container throws a NoUniqueBeanDefinitionException and fails to start.

<bean class="com.memorynotfound.spring.core.autowired.Person" autowire="constructor"/>
<bean class="com.memorynotfound.spring.core.autowired.Job" >
    <property name="name" value="Java Developer"/>
</bean>
<bean class="com.memorynotfound.spring.core.autowired.Job" >
    <property name="name" value="Java Developer"/>
</bean>

Output

The container will throw an NoUniqueBeanDefinitionException exception and fails to start.

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.memorynotfound.spring.core.autowired.Job] is defined: expected single matching bean but found 2: com.memorynotfound.spring.core.autowired.Job#0,com.memorynotfound.spring.core.autowired.Job#1

Spring Autowire by constructor – no candidate

With spring autowire by constructor enabled and there is no qualifying bean that matches the type, then nothing happens and the bean will not be initialized.

<bean class="com.memorynotfound.spring.core.autowired.Person" autowire="constructor"/>

Output

This will produce the following output if we call the toString method of the Person bean.

Person{name='John Doe', job=null}

References

Download

You may also like...