Meyyappan has posted 101 posts at DZone. View Full User Profile

Spring Constructor Injection

06.14.2012
| 52484 views |
  • submit to reddit

In this example you will learn how to set a bean property via constructor injection. Consider the following User bean class.

package com.vaannila;

    public class User {
    
    private String name;
    private int age;
    private String country;
    
    User(String name, int age, String country)
    {
        this.name=name;
        this.age=age;
        this.country=country;
    }
    
    public String toString() {
    	return name + " is " + age + " years old, living in " + country;
    }
}

 The User bean class has three attributes viz. name, age and country. All the three attributes are set thru constructor injection. The toString() method of the User bean class is overridden to display the user object.

Here the beans.xml file is used to do spring bean configuration. The following code shows how to set a property value thru constructor injection.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="user" class="com.vaannila.User" >
        <constructor-arg value="Eswar" />
        <constructor-arg value="24"/>
        <constructor-arg value="India"/>
    </bean>

</beans>

 The constructor-arg element within the bean element is used to set the property value thru constructor injection. Since there is only one constructor in the User bean class, this code will work fine. When there is more than one constructor with the same number of arguments, then the following ambiguities will occur. Conside the following code.

<bean id="user" class="com.vaannila.User" >
    <constructor-arg value="24"/>
    <constructor-arg value="India"/>
</bean>

</pre>
<p>
Now which constructor do you think will be invoked? The first one with the int and the String argument, right? But for your surprise it will call the second constructor with both String arguments. Though we know the first argument is of type int and the second argument is of type String, spring interprets both as String arguments.  To avoid this confusion you need to specify the <em>type</em> attribute of the <em>constructor-arg</em> element. Now with the following bean configuration, the first constructor will be invoked. </p>
<pre class="brush: xml; toolbar: false;">
<bean id="user" class="com.vaannila.User" >
    <constructor-arg type="int" value="24"/>
    <constructor-arg type="java.lang.String" value="India"/>
</bean>

 The constructor-arg element within the bean element is used to set the property value thru constructor injection. Since there is only one constructor in the User bean class, this code will work fine. When there is more than one constructor with the same number of arguments, then the following ambiguities will occur. Conside the following code.

User(String name, int age)
{
    this.name=name;
    this.age=age;
}

User( int age, String country)
{
    this.age=age;
    this.country=country;
}

 The bean configuration file.

<bean id="user" class="com.vaannila.User" >
    <constructor-arg type="int" value="24"/>
    <constructor-arg type="java.lang.String" value="India"/>
</bean>

 Now which constructor do you think will be invoked? The first one with the int and the String argument, right? But for your surprise it will call the second constructor with both String arguments. Though we know the first argument is of type int and the second argument is of type String, spring interprets both as String arguments. To avoid this confusion you need to specify the type attribute of the constructor-arg element. Now with the following bean configuration, the first constructor will be invoked.

<bean id="user" class="com.vaannila.User" >
    <constructor-arg type="int" value="24"/>
    <constructor-arg type="java.lang.String" value="India"/>
</bean>

Now which constructor do you think will be called? The second constructor, right? But again for your surprise the first constructor will be called, this is because the order in which the arguments appear in the bean configuration file will not be considered while invoking the constructor. To solve this problem you can use the index attribute to specify the constructor argument index.

Here is the bean configuration file after adding the index attribute.

<bean id="user" class="com.vaannila.User" >
    <constructor-arg index="0" type="int" value="24"/>
    <constructor-arg index="1" type="java.lang.String" value="India"/>
</bean>

Now as expected, the second constructor will be invoked.

You can download and try the constructor injection example by clicking the Download link below.

Source:  Download

Source + Lib:  Download

Published at DZone with permission of its author, Meyyappan Muthuraman.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags: