Sunday, January 12, 2014

Dependency Injection with Spring framework


Dependency Injection means inversion of responsibilities with regard to how an object obtains references to collaborating objects. When applying DI , objects are given their dependencies at creation time by some external entity that coordinates with each object in the system.

As you can see,  this process is inverse of what happens without DI .  The object itself is responsible for instantiating or locating the dependencies by using direct construction of classes  or a service locator .


Interface injection 
In Interface injection , class provides an interface that its users implements to get the dependencies at runtime .                                                                                      
Setter injection  
In setter injection , setter method of the dependent class is used by a framework to inject the dependencies .                                                                                                  
Constructor injection 
In this , the constructor of the dependent class is invoked by the framework to inject the dependencies . 

1. Cleaner code / better decoupling :
The code is cleaner and  decoupling is more effective  between the classes . With DI , the objects are no more responsible for acquiring their dependencies by their own .

2. Efficient Unit testing :
With DI , it is easier to inject mock implementations of a service into the object being tested.

I did a google search and found some interesting links that describes the benefits of DI :




DI with Spring framework.                            

In Spring DI exists in two variants :
1. Constructor-based DI.
2. Setter-based DI.

1. Constructor-based DI.
In constructor-based DI , the constructor of the dependent class is invoked by the spring container . Each argument of the constructor represents the dependency. 

public class Foo {
 private final Bar bar;

 public Foo(Bar bar) {
  this.bar = bar;
 }

}
For injecting Bar into Foo's constructor , we need to define their dependency in a configuration file as given below :
<beans>
 <bean id="bar" class="com.springdi.Bar"/>
 <bean id="foo" class="com.springdi.Foo">
  <constructor-arg ref="bar"/>
 </bean> 
</beans>





2. Setter-based DI.
In setter-based DI , container calls the setter methods on the bean . Container  invokes the no argument constructor or no argument static factory method to instantiate the bean .

public class Foo {
 private Bar bar;

 /**
 Bean contains a setter method that will be invoked by the container
 to inject the dependency.
 */
 public void setBar(Bar bar) {
  this.bar = bar;
 }
}
In the configuration file , we will define the dependency using the tag "property" and not "constructor-arg".
<beans>
 <bean id="bar" class="com.springdi.Bar"/>
 <bean id="foo" class="com.springdi.Foo">
  <property name="bar" ref="bar"/>
 </bean> 
</beans>
Constructor-based DI or Setter-based DI 
For mandatory dependencies , use constructor-based DI and  for optional dependencies , use setter-based DI .  

NOTE :
If we use @Required annotation with a setter , it becomes a required dependency .

No comments :

Post a Comment