Core Spring : Injection using property and constructor-arg and Injecting Objects

In the previous post we have seen how to create a simple spring project and how spring created an object for us using the configuration file. Now lets move on further by injecting depencies. Lets modify our Employee.java:


package mynotes.corespring.test;

public class Employee {

private int id;
 private String name;

public Employee(){

 }

 public Employee(int id, String name) {
 this.id = id;
 this.name = name;
 }
 @Override
 public String toString() {
 return ("Id=>"+this.id+" Name=>"+this.name);
 }

public int getId() {
 return id;
 }

public void setId(int id) {
 this.id = id;
 }

public String getName() {
 return name;
 }

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

}

We have 2 constructor, one a no argument constructor and one with fields. Lets initialise these fields using spring.xml:


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

 <bean id="employee" class="mynotes.corespring.test.Employee">
 <property name="id" value="100"></property>
 <property name="name" value="John"></property>
 </bean>

</beans>

Our App.java remains more or less same:


package mynotes.corespring.test;

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

public class App {

public static void main(String[] args) {
 ApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
 Employee employee=(Employee) context.getBean("employee");
 System.out.println(employee);
 }

}

Output:


Id=>100 Name=>John

Notice that in the property tag in spring.xml you defined id as string which spring automatically converted to int matching the type of the class. Lets go throught he constructor injection. Changing spring.xml:


<bean id="employee" class="mynotes.corespring.test.Employee">
<constructor-arg value="20"></constructor-arg>
<constructor-arg value="John"></constructor-arg>
</bean>

Running App.java:


Id=>20 Name=>John

Here spring took to constructor with arguments Employee(int id, String name) and assigned accordingly. Spring actually assumed here that your first <constructor-arg> is id and the second is name. If you reverse it in spring.xml:


<bean id="employee" class="mynotes.corespring.test.Employee">
<constructor-arg value="John"></constructor-arg>
<constructor-arg value="20"></constructor-arg>
</bean>

and now run App.java you will get the following exception:


Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employee' defined in class path resource [spring.xml]: Could not resolve matching constructor (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)

This could be solved by using index in the constructor-arg like:


<bean id="employee" class="mynotes.corespring.test.Employee">
<constructor-arg value="John" index="1"></constructor-arg>
<constructor-arg value="20" index="0"></constructor-arg>
</bean>

Now you code will run as expected. Another way to resolve such conflicts is by using type attribute in constructor-arg like:


<bean id="employee" class="mynotes.corespring.test.Employee">
<constructor-arg value="John" type="String"></constructor-arg>
<constructor-arg value="20" type="int"></constructor-arg>
</bean>

Lets add 2 addresses to our Employee class – homeAddress and officeAddress and modify the toString() to include it.


package mynotes.corespring.test;

public class Employee {

private int id;
private String name;
private Address homeAddress;
private Address officeAddress;

public Employee() {

}

public Employee(int id, String name) {
this.id = id;
this.name = name;
}

@Override
public String toString() {
return ("Id=>" + this.id + " Name=>" + this.name + "\nhomeAddress=>"
+ this.homeAddress + "\nofficeAddress=>" + this.officeAddress);
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

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

public Address getHomeAddress() {
return homeAddress;
}

public void setHomeAddress(Address homeAddress) {
this.homeAddress = homeAddress;
}

public Address getOfficeAddress() {
return officeAddress;
}

public void setOfficeAddress(Address officeAddress) {
this.officeAddress = officeAddress;
}

}

Address.java:


package mynotes.corespring.test;

public class Address {

private String street;
private String city;
private int pincode;

@Override
public String toString() {
return ("street::" + this.street + " city::" + this.city + " pincode::"
+ this.pincode);
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public int getPincode() {
return pincode;
}
public void setPincode(int pincode) {
this.pincode = pincode;
}

}

Lets modify our spring.xml to inject these:


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

<bean id="employee" class="mynotes.corespring.test.Employee">
<constructor-arg value="John" type="String"></constructor-arg>
<constructor-arg value="20" type="int"></constructor-arg>
<property name="homeAddress" ref="homeAddress"></property>
<property name="officeAddress" ref="officeAddress"></property>
</bean>

<bean id="homeAddress" class="mynotes.corespring.test.Address">
<property name="street" value="Street1"></property>
<property name="city" value="City1"></property>
<property name="pincode" value="123456"></property>
</bean>
<bean id="officeAddress" class="mynotes.corespring.test.Address">
<property name="street" value="Street2"></property>
<property name="city" value="City2"></property>
<property name="pincode" value="654321"></property>
</bean>

</beans>

Above we are creating 2 beans and initialzing them using property tags as explained previously. Now for creating Employee object we are still using the constructor-arg and for setting the vaues of adresses fiels we are using the property tag and refering it to th new beans we created. We can also create another constructor to take adreeses as input and then use constructor-arg. That depends on you design requirements.

Running App will show following output:


Id=>20 Name=>John
homeAddress=>street::Street1 city::City1 pincode::123456
officeAddress=>street::Street2 city::City2 pincode::654321

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: