Dependency Injection in Spring Framework

Dependency Injection
DI is design pattern that help us decouple the code. Design pattern is solution for common problems.

Decoupling-
Java components / classes should be as independent as possible of other Java classes.

Strong Dependency:

class A                                    
{                                           
  private B obj;                             
                                             
  public A(){                                 
  obj = new B;                               
 }                                           
}                                     

class B
{
  int x, y;

  public B(){
     x = 2;
     y = 3;                                       
  }
 }

Here, we can see strong coupling between class A and class B.
class A is initializing class B’s object inside its own constructor.
class A is dependent on class B.
If there is any change in class B, you need to change class A also, this is called as strong dependency.
For example, tomorrow if class B changes to

 class B
 {
   int x, y;

   public B(int x, int y){
      this.x = x;
      this.y = y;                                       
   }
  }

Then you have to do changes in class A like this-

 class A                                    
{                                           
  private B obj;                             
                                             
  public A(){                                 
  obj = new B(2, 3);                               
 }                                           
}      

Changes in one class causing change in another dependent class creates strong dependency between them.

So If you consider bigger picture such changes are never feasible, This is serious problem.
So remedy to this problem is Dependency Injection.

Solution 1:

 class A                                    
{                                           
  private B obj;                             
                                             
  public A(B obj){                                 
  this.obj = obj;                               
 }                                           
}     

class B
{
 int x, y;

 B(){ 
   x = 2;
   y = 3;
 }

 B(int x, int y){
   this.x = x;
   this.y = y;
 }
 
}

In Solution 1, I have passed object of class B in constructor of class A.
So future changes in implementation in class B, wont affect class A anymore.

Solution 2 :

class A                                    
{                                           
  private B obj;                             
                                             
  public void setObj(B obj){                                 
  this.obj = obj;                               
 }                                           
}   

Here, I have written Setter method for initialization of class B’s object, This is another solution for strong dependancy.

Now,

In both Solution I gonna need one Assembler class, which will create instance of Class B and will provide same to class A constructor in case of solution 1 or setter method in case of solution 2.

Class Assembler{
void assemble{

   B obj = new B();
   A a = new A(obj);

 //Or


   B obj = new B(1,2);
   A a = new A();
   a.setObj(obj);

 }
} 

Previously Control is in hand of class A, because A is creating object of B.
Now Control is transferred to Assembler class, It is instantiating B and supplying it to A, This is Inversion of Control.

Dependency Injection known as IoC: Inversion of Control. Martin Fowler brought jargon- Dependency Injection.

Dependency Injection Types:
1. Constructor Injection
2. Setter Injection
3. Interface Based Injection- This is not supported by Spring.

Code Demonstration:

Lets have a situation where class A is dependent on Class B.
Class A for us – StudentDetails
Class B for us – StudentInfo

package com.springmvc.bean;
public class StudentDetails {
    public StudentInfo stud;
    public StudentInfo getStud()
    {return stud;}
    public void setStud(StudentInfo stud) 
    {this.stud = stud;}
    public void display() {
     System.out.println("Student Name:"+stud.getName()+"  Student Id:"+stud.getId());
}
}

package com.springmvc.bean;
public class StudentInfo {
   String name,id;
   public String getName()
   {return name;}
   public void setName(String name)
   {this.name = name;}
   public String getId()
   {return id;}
   public void setId(String id)
   {this.id = id;}
   public void display()
   {System.out.println("StudentInfo");}
}

Assembler class:

public class ImplStudentInfo {
	public static void main(String args[]) {

		BeanFactory fac=new XmlBeanFactory(new FileSystemResource("spring.xml"));
		
		
		
		StudentDetails d=(StudentDetails)fac.getBean("StudentDetails");
		d.display();
		
	}
}

For setter Injection your spring.xml have bean definition like-

<bean id="StudentInfo" class="com.springmvc.bean.StudentInfo">
<property name="name" value="Pravin"></property>
<property name="id" value="1"></property>
</bean>
<bean id="StudentDetails" class="com.springmvc.bean.StudentDetails">
<property name="stud" ref="StudentInfo"></property>
</bean>

Here using property field we pass parameters to bean, Now StudentDetails bean requires StudentInfo Object to be injected.
which is achieved by “ref”
We specify name of bean to be injected as value for “ref”.

For Constructor Injection-

<bean id="StudentDetails" class="com.springmvc.bean.StudentDetails">
        <constructor-arg>
            <ref bean="StudentInfo"/>
        </constructor-arg>
   </bean>

Advantages of Dependency Injection:

1.Loosely couple architecture.

2.Separation of responsibility

3.Configuration and code is separate.

4.Using configuration, a different implementation can be supplied without changing the dependent code.

5.Testing can be performed using mock objects.

Advertisements

One response to “Dependency Injection in Spring Framework

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