In Setter based DI(Dependency Injection), Objects define their dependencies via properties (<property> tag) and Container invoke setter methods to set these properties in object instance after invoking a no-argument constructor or no-argument static factory method to instantiate the bean.
To make setter injection work No-Argument Constructor(Default/Explicit) or No-Argument Static factory method is required. In this topic we will discuss about the DI using no arg static factory method. Click here to learn Spring DI using No Arg Constructor.
Arg Static Factory Method can also be used but in that case argument will be passed as “constructor-arg” elements to specify arguments to the factory.
Bean Class(To Dependency Inject)
package com.jbt.bean;
import java.util.List;
public class Address1 {
public String flatNo;
public String bldgNo;
public String streetNo;
public String city;
public int pincode;
public String getStreetNo() {
return streetNo;
}
public void setStreetNo(String streetNo) {
System.out.println("Setter method is called");
this.streetNo = streetNo;
}
public String getFlatNo() {
return flatNo;
}
public void setFlatNo(String flatNo) {
this.flatNo = flatNo;
}
public String getBldgNo() {
return bldgNo;
}
public void setBldgNo(String bldgNo) {
this.bldgNo = bldgNo;
}
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;
}
private Address1() {
super();
System.out.println("Invoking No Arg Constructor");
}
static Address1 InitMethod() {
System.out.println("Init Method Invoked");
return new Address1();
}
@Override
public String toString() {
return "Address [flatNo=" + flatNo + ", bldgNo=" + bldgNo
+ ", streetNo=" + streetNo + ", city=" + city + ", pincode="
+ pincode + "]";
}
}
Here we have overriden “toString” method to view meaningfull output for the programmme.
Spring Configuration File
<?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-3.1.xsd">
<!-- Here we are using setter injection for DI -->
<!-- Name Attribute can be used to create one or more aliases for a Bean.
Multiple aliases can be separated by a spaces, commas, or semi-colons -->
<bean id="address" class="com.jbt.bean.Address" name="address1,address2" factory-method="InitMethod">
<property name="flatNo">
<value>203</value>
</property>
<property name="bldgNo">
<value>2C</value>
</property>
<property name="streetNo">
<value>JBT Street</value>
</property>
<property name="city">
<value>New York</value>
</property>
<property name="pincode">
<value>123456</value>
</property>
</bean>
</beans>
Here we have mentioned the init factory(factory-method attribute) method that needs to be used to create Object.
In Configuration file we use “class” attribute to provide the fully qualified name of the bean’s class.
And “name” attribute is used to create aliases(address1 & address2)
Execute Application(Dependency Inject Bean)
package com.jbt;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.jbt.bean.Address;
/*
* Here we will learn to Dependency Inject Bean with Setter injection.
*/
public class SpringDISetter {
public static void main(String[] args) {
ApplicationContext cpxac = new ClassPathXmlApplicationContext(
"applicationContext_DISetter.xml");
Address address = (Address) cpxac.getBean("address");
System.out.println("This is address Bean :::::" + address.toString());
/*
* address1 & address2 are the alias name for address id. Alias name can
* be defined in XML file using "name" attribute.
*/
Address address1 = (Address) cpxac.getBean("address1");
Address address2 = (Address) cpxac.getBean("address2");
System.out.println("This is address Bean 1:::::" + address1.toString());
System.out.println("This is address Bean 2:::::" + address2.toString());
}
}
Output of the above programme
Init Method Invoked
Invoking No Arg Constructor
Setter method is called
This is address Bean :::::Address [flatNo=203, bldgNo=2C, streetNo=JBT Street, city=New York, pincode=123456]
This is address Bean 1:::::Address [flatNo=203, bldgNo=2C, streetNo=JBT Street, city=New York, pincode=123456]
This is address Bean 2:::::Address [flatNo=203, bldgNo=2C, streetNo=JBT Street, city=New York, pincode=123456]
Important Points related to Factory Method:
- Return type should be Non Void.
- Factory Method needs to be static.
- Autowiring does not apply to factory methods.
- Factory method can have any number of arguments.(Not Applicable to this situation)
- If Factory method takes arguments it should be specified by constructor-arg elements.
Environment Used
Tool : Eclipse Indigo
Java : JDK 1.6
Spring : 3.1.1
Jars Required :
- org.springframework.core-3.1.1.RELEASE.jar
- org.springframework.context-3.1.1.RELEASE.jar
- org.springframework.asm-3.1.1.RELEASE.jar
- org.springframework.beans-3.1.1.RELEASE.jar
- org.springframework.expression-3.1.1.RELEASE.jar
- commong-logging-1.1.1.jar