Setter Injection – Type of Dependency Injection
Dec 2nd, 2009 | By admin | Category: SpringI have discussed on the concept of Dependency Injection in my last post . This post is about a specific type of Dependency Injection adopted by Spring. It is called Setter Injection. In Java POJO(Plain old java object) world , setters and getters are very common terms. A setter which sets an attribute value of a class. A getter which return the attribute value of a class.
Dependency can be injected using the setter method of a class. If a class is dependent on another class or primitive variables then the dependency should be declared as a state(variable) of the class and the class should have a setter method for it.
For an example , lets say Employee class is dependent on Address class , Employee class should have a state variable and a setter method , like ,
Listing 1 : Class with a setter method
private Address address;
public void setAddress(Address address) {
this.address = address;
}
The Spring IOC container should inject the address dependency using the setter method of Address. Whole dependency Injection is push method where a dependency value will be pushed and a client class should not bother about pulling the dependency back from anywhere. Lets learn to set setter dependency injection with following example.
Lets assume , we have a class relation like the following ,
Listing 2 : Class Relations
Employee has an Address and a Project
Look at the above class relations. Employee has an Address and Employee has a Project. Employee is dependent on both Address and Project classes directly. Using Spring IOC controller we can inject the dependency values to Employee class . Lets do it.
Spring IOC container needs a bean to be defined for all kind of classes whose object should be created for your application. For the above application we need instance of an Address class , Project Class and at last Employee class to get the employee data. Hence we need three beans to be declared. Beans should be declared in the application context xml file. The
<bean>
tag should define a bean with it’s properties and
Address class has three properties , i.e , street , city and pincode. Hence the bean for the Address class is defined as follows ,
Listing 3 : Address Bean
<bean id="addressBean"
class="com.company.spring.injection.setter.model.Address">
<property name="street">
<value>Bagmane Tech park</value>
</property>
<property name="city">
<value>Bangalore</value>
</property>
<property name="pincode">
<value>566093</value>
</property>
</bean>
Intention is to instantiate the Address class and populate it’s properties with respective values. Similar way , a bean definition for Project class could be as,
Listing 4 : Project Bean
<bean id="projectBean"
class="com.company.spring.injection.setter.model.Project">
<property name="projectName">
<value>iManager</value>
</property>
<property name="department">
<value>ISM</value>
</property>
<property name="teamMemberCount">
<value>10</value>
</property>
<property name="deliveryDate">
<ref bean="dateBean"/>
</property>
</bean>
Point to notice is that the bean id is a logical name which can be any user friendly and non-objectionable
name. Look at these bean definition closely. Each bean has property and each property is populated with some value. But thing is different for deliveryDate bean in projectBean. There is a
<ref>
tag instead of
<value>
. Because deliveryDate property is of type java.util.Date in Project class so we need a java.util.Date reference to set it’s value. So we need another bean for date.
Listing 5 : Date Bean
<bean id="dateBean" class="java.util.Date"/>
Now , lets have a look at the bean for the Employee class.
Listing 6 : Employee Bean
<bean id="employeeBean"
class="com.company.spring.injection.setter.model.Employee">
<property name="name" value="Tapas Adhikary"></property>
<property name="empId" value="88699"></property>
<property name="address" ref="addressBean"></property>
<property name="project" ref="projectBean"></property>
</bean>
See the last two properties of the employeeBean bean. We have injected the addressBean and projectBean as a reference to the properties names address and project respectively. So your client code ( Where we have decided to create and instance of Employee and call it’s getter methods) should not worry about setting all this values. Employee’s dependencies will be pushed by the Spring IOC container.
The client code should be like this ,
Listing 7 : Setter Injection Java file
public class SetterInjection {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
"resources/applicationContext.xml");
BeanFactory factory = (BeanFactory) context;
Employee employee = (Employee) factory.getBean("employeeBean");
Address address = employee.getAddress();
Project project = employee.getProject();
System.out.println(employee.getName());
System.out.println(employee.getEmpId());
System.out.println(address.getCity());
System.out.println(address.getStreet());
System.out.println(address.getPincode());
System.out.println(project.getProjectName());
System.out.println(project.getDepartment());
System.out.println(project.getTeamMemberCount());
System.out.println(project.getDeliveryDate().toString());
}
}
Lets assume the application context file name is applicationContext.xml and it’s under a folder called resources. An ApplicationContext object should be formed with the help of the xml file. The context object is type of the Bean Factory which uses the Factory Design Pattern concept to create the object. Once you get the factory , you need to query the bean using the bean name , i.e , employeeBean. Thats it. Your Employee class is instantiated. Now you can get all the Employee properties including Address and Project properties injected using the xml file and the setter method of Address , Person and Employee.
The attached source code has the full version of the xml and all java source files. Download the code and import into your favorite IDE.
I would like to conclude this post with one rule. A property name of a bean in the xml file should be equal to the setter method name of the attribute of the class without the word set at the beginning . Say if the property name of a bean in the application context xml file is departmentName then the corresponding class should have a setter method called
public void setDepartmentName(String departMent){
// Set the value
}
Note : ‘D’ is in capital in the setter method after the word ’set’.
