Autowire Spring Bean Constructor Injection Examples

This example will show you how to use constructor injection to autowire spring bean as another bean’s constructor parameters.

1. Not Autowired Spring Bean Constructor Injection.

  1. This example has three spring beans defined. They are companyBeanApple, companyBeanIBM and employeeBean.
  2. employeeBean ‘s constructor has five parameters and the parameters are specified manually.
  3. The first three parameters are all java.lang.String type and the last two constructor parameter refer to companyBeanApple and companyBeanIBM. Below is the detailed XML configuration.
    <bean id="companyBeanApple" class="com.dev2qa.example.spring.bean.autowire.byconstructor.CompanyBean"> 
          <property name="companyName" value="Apple Inc"></property> 
          <property name="companyAddress" value="Palo alto"></property> 
          <property name="companyProducts" value="iPhone, iPad, iMac"></property> 
    </bean> 
    
    <bean id="companyBeanIBM" class="com.dev2qa.example.spring.bean.autowire.byconstructor.CompanyBean"> 
          <property name="companyName" value="IBM Inc"></property> 
          <property name="companyAddress" value="New York"></property> 
          <property name="companyProducts" value="PC, Notebook"></property> 
    </bean> 
    
    <bean id="employeeBean" class="com.dev2qa.example.spring.bean.autowire.byconstructor.EmployeeBean"> 
          <constructor-arg type="java.lang.String" value="Jerry" index="0"> </constructor-arg> 
          <constructor-arg type="java.lang.String" value="199999" index="1"> </constructor-arg> 
          <constructor-arg type="java.lang.String" value="Java, Spring, JDBC" index="2"> </constructor-arg> 
          <constructor-arg type="com.dev2qa.example.spring.bean.autowire.byconstructor.CompanyBean" ref="companyBeanIBM" index="3"> </constructor-arg> 
          <constructor-arg type="com.dev2qa.example.spring.bean.autowire.byconstructor.CompanyBean" ref="companyBeanApple" index="4"> </constructor-arg> 
    </bean>
  4. Please Note: For <constructor-arg XML element, index value starts from 0 and do not set it’s index attribute and name attribute simultaneously, otherwise, a org.springframework.beans.factory.UnsatisfiedDependencyException will be thrown and the error message may be like “Unsatisfied dependency expressed through constructor argument with index 0 of type [java.lang.String]: Ambiguous constructor argument types – did you specify the correct bean references as constructor arguments?“.
  5. CompanyBean.java
    // Store one company info.
    public class CompanyBean {
    	
    	private String companyName;
    	
    	private String companyAddress;
    	
    	private String companyProducts;
    
    	public String getCompanyName() {
    		return companyName;
    	}
    
    	public void setCompanyName(String companyName) {
    		this.companyName = companyName;
    	}
    
    	public String getCompanyAddress() {
    		return companyAddress;
    	}
    
    	public void setCompanyAddress(String companyAddress) {
    		this.companyAddress = companyAddress;
    	}
    
    	public String getCompanyProducts() {
    		return companyProducts;
    	}
    
    	public void setCompanyProducts(String companyProducts) {
    		this.companyProducts = companyProducts;
    	}
    }
    
  6. EmployeeBean.java
    public class EmployeeBean {
    	
    	private String employeeName;
    	
    	private String employeeSalary;
    	
    	private String employeeSkill;
    	
    	private CompanyBean employeeCompanyOld;
    	
    	private CompanyBean employeeCompanyNew;
    
    
    	public String getEmployeeName() {
    		return employeeName;
    	}
    
    	public void setEmployeeName(String employeeName) {
    		this.employeeName = employeeName;
    	}
    
    	public String getEmployeeSalary() {
    		return employeeSalary;
    	}
    
    	public void setEmployeeSalary(String employeeSalary) {
    		this.employeeSalary = employeeSalary;
    	}
    
    	public String getEmployeeSkill() {
    		return employeeSkill;
    	}
    
    	public void setEmployeeSkill(String employeeSkill) {
    		this.employeeSkill = employeeSkill;
    	}
    
    	public CompanyBean getEmployeeCompanyOld() {
    		return employeeCompanyOld;
    	}
    
    	public void setEmployeeCompanyOld(CompanyBean employeeCompanyOld) {
    		this.employeeCompanyOld = employeeCompanyOld;
    	}
    
    	public CompanyBean getEmployeeCompanyNew() {
    		return employeeCompanyNew;
    	}
    
    	public void setEmployeeCompanyNew(CompanyBean employeeCompanyNew) {
    		this.employeeCompanyNew = employeeCompanyNew;
    	}
    
    	// EmployeeBean constructor with arguments.
    	public EmployeeBean(String employeeName, String employeeSalary, String employeeSkill, CompanyBean employeeCompanyOld, CompanyBean employeeCompanyNew) {
    		this.employeeName = employeeName;
    		this.employeeSalary = employeeSalary;
    		this.employeeSkill = employeeSkill;
    		this.employeeCompanyOld = employeeCompanyOld;
    		this.employeeCompanyNew = employeeCompanyNew;
    	}
    
    	public static void main(String[] args) {
    
    	   	// Initiate Spring application context, this line code will invoke bean initialize method.
    		ApplicationContext springAppContext = new ClassPathXmlApplicationContext("BeanSettings.xml");
    
    		// Get EmployeeBean by id. 
    		EmployeeBean employeeBean = (EmployeeBean) springAppContext.getBean("employeeBean");
    		
            System.out.println("Employee name : " + employeeBean.getEmployeeName());
            
            System.out.println("Employee salary : " + employeeBean.getEmployeeSalary());
            
            System.out.println("Employee skill : " + employeeBean.getEmployeeSkill());
            
            System.out.println("Old company name : " + employeeBean.getEmployeeCompanyOld().getCompanyName());
            
            System.out.println("Old company address : " + employeeBean.getEmployeeCompanyOld().getCompanyAddress());
            
            System.out.println("Old company products : " + employeeBean.getEmployeeCompanyOld().getCompanyProducts());
            
            System.out.println("New company name : " + employeeBean.getEmployeeCompanyNew().getCompanyName());
            
            System.out.println("New company address : " + employeeBean.getEmployeeCompanyNew().getCompanyAddress());
            
            System.out.println("New company products : " + employeeBean.getEmployeeCompanyNew().getCompanyProducts());
    	}
    
    }
    
  7. Above example execution output.
    Employee name : Jerry
    Employee salary : 199999
    Employee skill : Java, Spring, JDBC
    Old company name : IBM Inc
    Old company address : New York
    Old company products : PC, Notebook
    New company name : Apple Inc
    New company address : Palo alto
    New company products : iPhone, iPad, iMac

2. Make Above Spring Bean Autowired.

  1. To make reference type constructor parameter autowired, you just need to add autowire="constructor" in employeeBean definition like below.
     <bean id="employeeBean" class="com.dev2qa.example.spring.bean.autowire.byconstructor.EmployeeBean" 
           autowire="constructor"> 
           <constructor-arg type="java.lang.String" value="Jerry" index="0"> </constructor-arg> 
           <constructor-arg type="java.lang.String" value="199999" index="1"> </constructor-arg> 
           <constructor-arg type="java.lang.String" value="Java, Spring, JDBC" index="2"> </constructor-arg> 
    </bean>
  2. Run the above example again, you will get the exception org.springframework.beans.factory.NoUniqueBeanDefinitionException, the error message is “No qualifying bean of type [com.dev2qa.example.spring.bean.autowire.byconstructor.CompanyBean] is defined: expected single matching bean but found 2: companyBeanApple, companyBeanIBM“.
  3. So we can see spring bean constructor parameter auto-injection will inject bean by type. To fix this issue, you should use a unique class type constructor parameter or use a java.util.List parameter to group same class type parameter.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.