Spring bean autowire by constructor

In Spring framework, bean autowiring by constructor is similar to byType, but applies to constructor arguments. In autowire enabled bean, it look for class type of constructor arguments, and then do a autowire by type on all constructor arguments.

Please note that if there isn’t exactly one bean of the constructor argument type in the container, a fatal error is raised.

Read More : Spring bean autowiring modes

Bean autowiring by constructor

How to enable constructor autowiring

Autowiring by constructor is enabled by using autowire="constructor" in bean definition in configuration file (i.e. application-context.xml).

A typical bean configuration file will look like this:

<?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-3.0.xsd
	http://www.springframework.org/schema/context/
	http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:annotation-config />
    
	<bean id="employee" class="com.howtodoinjava.autowire.constructor.EmployeeBean" autowire="constructor">
		<property name="fullName" value="Lokesh Gupta"/> 
	</bean>
 
	<bean id="department" class="com.howtodoinjava.autowire.constructor.DepartmentBean" >
		<property name="name" value="Human Resource" />
	</bean>

</beans>

Create constructor dependency

In above configuration, I have enabled the autowiring by constructor for ‘employee‘ bean. It has been done by passing constructor arguments.

package com.howtodoinjava.autowire.constructor;

public class EmployeeBean
{
	private String fullName;
	
	public EmployeeBean(DepartmentBean departmentBean)
	{
		this.departmentBean = departmentBean;
	}
	
	private DepartmentBean departmentBean;

	public DepartmentBean getDepartmentBean() {
		return departmentBean;
	}

	public void setDepartmentBean(DepartmentBean departmentBean) {
		this.departmentBean = departmentBean;
	}

	public String getFullName() {
		return fullName;
	}

	public void setFullName(String fullName) {
		this.fullName = fullName;
	}
}

And DepartmentBean looks like this which has been set:

package com.howtodoinjava.autowire.constructor;

public class DepartmentBean{
	private String name;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

Test the dependency

To test that bean has been set properly using constructor based autowiring, run following code:

package com.howtodoinjava.autowire.constructor;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestAutowire {
	public static void main(String[] args) {
		ApplicationContext context = 
		    	  new ClassPathXmlApplicationContext(new String[] {"com/howtodoinjava/autowire/constructor/application-context.xml"});
		 
		    	EmployeeBean employee = (EmployeeBean)context.getBean("employee");

		    	System.out.println(employee.getFullName());

		    	System.out.println(employee.getDepartmentBean().getName());
	}
}

Output:

Lokesh Gupta
Human Resource

Clearly, dependency was injected by constructor successfully.

Using constructor-arg

If you are NOT using autowire="constructor" in bean definition, then you will have to pass the constructor-arg as follows to inject department bean in employee bean:

<bean id="employee" class="com.howtodoinjava.autowire.constructor.EmployeeBean">
	<property name="fullName" value="Lokesh Gupta"/> 
	<constructor-arg>
		<ref bean="department" />
	</constructor-arg>
</bean>

Drop me your questions in comments section.

Happy Learning !!

Was this post helpful?

Join 7000+ Fellow Programmers

Subscribe to get new post notifications, industry updates, best practices, and much more. Directly into your inbox, for free.

4 thoughts on “Spring bean autowire by constructor”

  1. Hi Lokesh,

    I am not getting error even if I create more than one bean of the constructor argument type in the container. Thanks in Advance.

    
    <bean id="employee" class="com.howtodoinjava.autowire.constructor.EmployeeBean" autowire="constructor">
            <property name="fullName" value="Lokesh Gupta"/>
        </bean>
      
        <bean id="department" class="com.howtodoinjava.autowire.constructor.DepartmentBean" >
            <property name="name" value="Human Resource" />
        </bean>
    
    <bean id="departmentOne" class="com.howtodoinjava.autowire.constructor.DepartmentBean" >
            <property name="name" value="Finance" />
        </bean>
    
    Reply
    • You must be doing something wrong. I just tested the example again and it failed as expected.

      WARNING: Exception encountered during context initialization - cancelling refresh attempt: 
      org.springframework.beans.factory.UnsatisfiedDependencyException: 
      Error creating bean with name 'employee' defined in class path resource [application-context.xml]: 
      Unsatisfied dependency expressed through constructor parameter 0; 
      nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: 
      No qualifying bean of type 'com.howtodoinjava.autowire.constructor.DepartmentBean' available: 
      expected single matching bean but found 2: department,departmentOne
      Reply
  2. Your example is doing too much, obfuscating the lesson. I came to learn about auto wiring the constructor. Why isn’t full name part of the constructor injection? Whats the point of adding full name to the example? This is just clutter and it detracts from the lesson. Same with department bean name. Another non constructor wiring – what point does it add to the example?

    Despite all this unnecessary clutter, you skimp the meat of the meal. The lesson doesn’t provide much detail about the EmployeeBean constructor injection. Somehow springs just magically figures out to pass the DepartmentBean instance to the EmployeeBean constructor. I would be interested in what is going on here behind the scenes. This is the nut of the lesson – not Spring setter injections.

    Reply
    • Thanks for the feedback. I appreciate you time.
      1) “Why isn’t full name part of the constructor injection?” – Why it should be? It’s way to show that you can have setter as well as constructor injection – “both” – in same bean definition.
      2) “Same with department bean” – It is present in example because it has to be injected into other bean. There is absolutely no necessity to do constructor autowiring to make sense out of this example.
      3) “lesson doesn’t provide much detail about the EmployeeBean constructor injection” – I have clearly written that Autowiring by constructor is enabled by using autowire="constructor" in bean definition in configuration file [ In section Autowire dependency using constructor ]. And that’s how it is done in most cases.

      And read 3rd para of post for more clarity. Now I am making it bold.

      But thanks again for asking the questions, it means information may confuse others as well – so I have added info box with additional information to save other’s time.

      Reply

Leave a Comment

HowToDoInJava

A blog about Java and its related technologies, the best practices, algorithms, interview questions, scripting languages, and Python.