Spring Framework : A Framework from SpringSource :: Spring Dependency Injection
- What is Dependency Injection?
- Setter based Dependency Injection
- Constructor based Dependency Injection
- Bean Factory
- Download Examples
What is Dependency Injection? |
- The basic principle behind Dependency Injection (DI) is that objects define their dependencies (that is to say the other objects they work with) only through constructor arguments, arguments to a factory method, or properties which are set on the object instance after it has been constructed or returned from a factory method. Then, it is the job of the container to actually inject those dependencies when it creates the bean.
- This is fundamentally the inverse, hence the name Inversion of Control (IoC), of the bean itself being in control of instantiating or locating its dependencies on its own using direct construction of classes, or something like the Service Locator pattern.
DI exists in three major variants namely
Setter Injection
(e.g. Spring): Dependencies are assigned through JavaBeans properties (ex: setter methods).
Through setters methods framework will update the attribute values from the xml file, this is called setters injection.
Constructor Injection.
(e.g. Pico container, Spring etc): Dependencies are provided as constructor parameters.
Setting the value or injecting state of an object through the parameterized constructor is called constructor injection.
Method Injection (e.g. Avalon):
Note: Spring supports only Constructor and Setter Injection
Setter-based DI |
- It is realized by calling setter methods on your beans after invoking a no-argument constructor or no-argument static factory method to instantiate your bean.
- Find the following example of a class that can only be dependency injected using pure setter injection.
Address.Java
package com.javaskool;
public class Address {
private String houseNo;
private String streetName;
public String getHouseNo() {
return houseNo;
}
public void setHouseNo(String houseNo) {
this.houseNo = houseNo;
}
public String getStreetName() {
return streetName;
}
public void setStreetName(String streetName) {
this.streetName = streetName;
}
}
Student.java
package com.javaskool;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Properties;
public class Student {
private String firstName;
private int age;
private Double weight;
private String[] email;
private int marks[];
private ArrayList educations;
private HashSet lovers;
private HashMap jobs;
private Address permanentAddress;
private Properties mobileNos;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Double getWeight() {
return weight;
}
public void setWeight(Double weight) {
this.weight = weight;
}
public String[] getEmail() {
return email;
}
public void setEmail(String[] email) {
this.email = email;
}
public int[] getMarks() {
return marks;
}
public void setMarks(int[] marks) {
this.marks = marks;
}
public ArrayList getEducations() {
return educations;
}
public void setEducations(ArrayList educations) {
this.educations = educations;
}
public HashSet getLovers() {
return lovers;
}
public void setLovers(HashSet lovers) {
this.lovers = lovers;
}
public HashMap getJobs() {
return jobs;
}
public void setJobs(HashMap jobs) {
this.jobs = jobs;
}
public Address getPermanentAddress() {
return permanentAddress;
}
public void setPermanentAddress(Address permanentAddress) {
this.permanentAddress = permanentAddress;
}
public Properties getMobileNos() {
return mobileNos;
}
public void setMobileNos(Properties mobileNos) {
this.mobileNos = mobileNos;
}
}
applicationContext.xml
<?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-2.0.xsd">
<bean id="Myadd" class="com.javaskool.Address">
<property name="streetName" value="Meridian Layout"></property>
<property name="houseNo" value="G55"></property>
</bean>
<bean id="sobj" class="com.javaskool.Student">
<property name="firstName" value="James"></property>
<property name="age" value="32"></property>
<property name="weight" value="71.96"></property>
<property name="email">
<list>
<value>contact@javaskool.com</value>
<value>consult@javaskool.com</value>
<value>info@gmail.com</value>
</list>
</property>
<property name="marks">
<list>
<value>88</value>
<value>99</value>
<value>77</value>
</list>
</property>
<property name="educations">
<list>
<value>12th</value>
<value>Degree</value>
<value>M.Tech</value>
</list>
</property>
<property name="lovers">
<set>
<value>Ivone</value>
<value>Spring</value>
<value>Java</value>
</set>
</property>
<property name="jobs">
<map>
<entry key="job1" value="Developer"/>
<entry key="job2" value="Sr. Developer"/>
<entry key="job3" value="Programmer"/>
</map>
</property>
<property name="permanentAddress" ref="Myadd"></property>
<property name="mobileNos">
<props>
<prop key="Firstno">8080808080</prop>
<prop key="secondno">9090909090</prop>
</props>
</property>
</bean>
</beans>
TestDrive.java
package com.javaskool;
import java.util.Arrays;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class TestDrive {
public static void main(String[] args)
{
Resource res = new ClassPathResource("applicationContext.xml");
BeanFactory beans=new XmlBeanFactory(res);
Student p=(Student)beans.getBean("sobj"); //getting Student Object from BeanFactory
System.out.println(p.getFirstName());
System.out.println(p.getAge());
System.out.println(p.getWeight());
System.out.println(Arrays.toString(p.getEmail()));
System.out.println(Arrays.toString(p.getMarks()));
System.out.println(p.getEducations());
System.out.println(p.getLovers());
System.out.println(p.getJobs());
System.out.println(p.getPermanentAddress().getHouseNo());
System.out.println(p.getPermanentAddress().getStreetName());
System.out.println(p.getMobileNos());
}
}
Output
James
32
71.96
[contact@javaskool.com, consult@javaskool.com, info@gmail.com]
[88, 99, 77]
[12th, Degree, M.Tech]
[Ivone, Spring, Java]
{job1=Developer, job2=Sr. Developer, job3=Programmer}
G55
Meridian Layout
{Firstno=8080808080, secondno=9090909090}
Constructor-based DI |
- It is realized by invoking a constructor with a number of arguments, each representing a collaborator.
- Additionally, calling a static factory method with specific arguments to construct the bean, can be considered almost equivalent, and the rest of this text will consider arguments to a constructor and arguments to a static factory method similarly.
- Find the following example of a class that could only be dependency injected using constructor injection.
Address.Java
package com.javaskool;
public class Address {
private String houseNo;
private String streetName;
public String getHouseNo() {
return houseNo;
}
public void setHouseNo(String houseNo) {
this.houseNo = houseNo;
}
public String getStreetName() {
return streetName;
}
public void setStreetName(String streetName) {
this.streetName = streetName;
}
}
Student.java
package com.javaskool;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Properties;
public class Student {
private String firstName;
private int age;
private Double weight;
private String[] email;
private int marks[];
private ArrayList educations;
private HashSet lovers;
private HashMap jobs;
private Address permanentAddress;
private Properties mobileNos;
public Student(String firstName, int age, Double weight, String[] email,
int[] marks, ArrayList educations, HashSet lovers, HashMap jobs,
Address permanentAddress, Properties mobileNos) {
this.firstName = firstName;
this.age = age;
this.weight = weight;
this.email = email;
this.marks = marks;
this.educations = educations;
this.lovers = lovers;
this.jobs = jobs;
this.permanentAddress = permanentAddress;
this.mobileNos = mobileNos;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Double getWeight() {
return weight;
}
public void setWeight(Double weight) {
this.weight = weight;
}
public String[] getEmail() {
return email;
}
public void setEmail(String[] email) {
this.email = email;
}
public int[] getMarks() {
return marks;
}
public void setMarks(int[] marks) {
this.marks = marks;
}
public ArrayList getEducations() {
return educations;
}
public void setEducations(ArrayList educations) {
this.educations = educations;
}
public HashSet getLovers() {
return lovers;
}
public void setLovers(HashSet lovers) {
this.lovers = lovers;
}
public HashMap getJobs() {
return jobs;
}
public void setJobs(HashMap jobs) {
this.jobs = jobs;
}
public Address getPermanentAddress() {
return permanentAddress;
}
public void setPermanentAddress(Address permanentAddress) {
this.permanentAddress = permanentAddress;
}
public Properties getMobileNos() {
return mobileNos;
}
public void setMobileNos(Properties mobileNos) {
this.mobileNos = mobileNos;
}
}
applicationContext.xml
<?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-2.0.xsd">
<bean id="Myadd" class="com.javaskool.Address">
<property name="streetName" value="Meridian Layout"></property>
<property name="houseNo" value="G55"></property>
</bean>
<bean id="sobj" class="com.javaskool.Student">
<constructor-arg index="0" value="james"/>
<constructor-arg index="1" value="24"/>
<constructor-arg index="2" value="71.96"/>
<constructor-arg index="3" >
<list>
<value>contact@javaskool.com</value>
<value>consult@javaskool.com</value>
<value>info@gmail.com</value>
</list>
</constructor-arg>
<constructor-arg index="4">
<list>
<value>59</value>
<value>99</value>
<value>77</value>
</list>
</constructor-arg>
<constructor-arg index="5">
<list>
<value>12th</value>
<value>Degree</value>
<value>B.Tech</value>
</list>
</constructor-arg>
<constructor-arg index="6">
<set>
<value>Ivone</value>
<value>Spring</value>
<value>Java</value>
</set>
</constructor-arg>
<constructor-arg index="7" >
<map>
<entry key="job1" value="Developer"/>
<entry key="job2" value="Sr. Developer"/>
<entry key="job3" value="Programmer"/>
</map>
</constructor-arg>
<constructor-arg index="8" ref="Myadd"/>
<constructor-arg index="9" >
<props>
<prop key="Firstno">9090909090</prop>
<prop key="secondno">8080808080 </prop>
</props>
</constructor-arg>
</bean>
</beans>
TestDrive.java
package com.javaskool;
import java.util.Arrays;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class TestDrive {
public static void main(String[] args)
{
Resource res = new ClassPathResource("applicationContext.xml");
BeanFactory beans=new XmlBeanFactory(res);
Student p=(Student)beans.getBean("sobj"); //getting Student Object from BeanFactory
System.out.println(p.getFirstName());
System.out.println(p.getAge());
System.out.println(p.getWeight());
System.out.println(Arrays.toString(p.getEmail()));
System.out.println(Arrays.toString(p.getMarks()));
System.out.println(p.getEducations());
System.out.println(p.getLovers());
System.out.println(p.getJobs());
System.out.println(p.getPermanentAddress().getHouseNo());
System.out.println(p.getPermanentAddress().getStreetName());
System.out.println(p.getMobileNos());
}
}
Output
james
24
71.96
[contact@javaskool.com, consult@javaskool.com, info@gmail.com]
[59, 99, 77]
[12th, Degree, B.Tech]
[Ivone, Spring, Java]
{job1=Developer, job2=Sr. Developer, job3=Programmer}
G55
Meridian Layout
{Firstno=9090909090, secondno=8080808080}
Note: that there is nothing special about this class as it is plain old Java.
BeanFactory |
The BeanFactory supports both of these variants for injecting dependencies into beans it manages. (It in fact also supports injecting setter-based dependencies after some dependencies have already been supplied via the constructor approach.) The configuration for the dependencies comes in the form of a BeanDefinition, which is used together with PropertyEditor instances to know how to convert properties from one format to another. However, most users of Spring will not be dealing with these classes directly (that is programmatically), but rather with an XML definition file which will be converted internally into instances of these classes, and usedto load an entire Spring IoC container instance.
Bean dependency resolution generally happens as follows:
- The BeanFactory is created and initialized with a configuration which describes all the beans. (Most Spring users use a BeanFactory or ApplicationContext implementation that supports XML format configuration files.)
- Each bean has dependencies expressed in the form of properties, constructor arguments, or arguments to the static-factory method when that is used instead of a normal constructor. These dependencies will be provided to the bean, when the bean is actually created.
- Each property or constructor argument is either an actual definition of the value to set, or a reference to another bean in the container.
- Each property or constructor argument which is a value must be able to be converted from whatever format it was specified in, to the actual type of that property or constructor argument. By default Spring can convert a value supplied in string format to all built-in types, such as int, long, String, boolean, etc.
The Spring container validates the configuration of each bean as the container is created, including the validation that properties which are bean references are actually referring to valid beans. However, the bean properties themselves are not set until the bean is actually created. For those beans that are singleton-scoped and set to be pre-instantiated (such as singleton beans in an ApplicationContext), creation happens at the time that the container is created, but otherwise this is only when the bean is requested. When a bean actually has to be created, this will potentially cause a graph of other beans to be created, as its dependencies and its dependencies’ dependencies (and so on) are created and assigned.
Click Below to download the Examples
Recent Comments