Sunday, 12 April 2009

Dependency Injection in Spring

What is Dependency Injection:

Originally, dependency injection was commonly referred to by another name inversion of control(IoC). But in an article written in early 2004,
Martin Fowler asked what aspect of control is being inverted. He concluded that it is the acquisition of dependencies that is being inverted.

In the Java community there's been a rush of lightweight containers that help to assemble components from different projects into a cohesive application.(Ex: Spring) Underlying these containers is a common pattern to how they perform the wiring, a concept they refer under the very generic name of "Inversion of Control"

For this new breed of containers the inversion is about how they lookup a plugin implementation. The approach that these containers use is to ensure that any user of a plugin follows some convention that allows a separate assembler module to inject the implementation into the lister.

Based on that revelation, he coined the phrase “dependency injection,” a term that better describes what is going on. Inversion of Control is a generic term and the more specific name for this pattern is Dependency Injection.

Dependency injection is basically giving an object what it needs instead of letting this object get it by itself. It is based on a best practice technique (design pattern). This technique allows a part of application to be changed without causing problems in other areas of the application. A design is inflexible unless it cannot be easily adapted.

Why use Dependency Injection:

Instead of using Depenedency Injection if we hardcode "new" in our code.
What if something changes?
How do we externalize configuration from Java code, important if things change?

By avoiding use of a custom factory we are reducing extra code to be written in the application

By applying Dependency Injection in your projects, you’ll find that your code will become significantly simpler, easier to understand, and easier to test.

Any nontrivial application is made up of two or more classes that collaborate with each other to perform some business logic. Traditionally,
each object is responsible for obtaining its own references to the objects it collaborates with (its dependencies). This can lead to highly coupled and hard-to-test code. When applying Dependency injection(DI), objects are given their dependencies at creation time by some external entity that coordinates each object in the system. In other words, dependencies are injected into objects. So, DI means an inversion of responsibility with regard to how an object obtains references to collaborating objects.

Software components (Clients), are often a part of a set of collaborating components which depend upon other components (Services) to successfully complete their intended purpose. In many scenarios, they need to know “which” components to communicate with, “where” to locate them, and “how” to communicate with them. When the way such services can be accessed is changed, such changes can potentially require the source of lot of clients to be changed.

One way of structuring the code is to let the clients embed the logic of locating and/or instantiating the services as a part of their usual logic. Another way to structure the code is to have the clients declare their dependency on services, and have some "external" piece of code assume the responsibility of locating and/or instantiating the services and simply supplying the relevant service references to the clients when needed. In the latter method, client code typically is not required to be changed when the way to locate an external dependency changes. This type of implementation is considered to be an implementation of Dependency Injection and the "external" piece of code referred to earlier is likely to be either hand coded or implemented using one of a variety of DI frameworks.

Dependency Injection uses the Hollywood Principle: “Don’t call me, I’ll call you.” In other words, your classes don’t look up or instantiate the classes they depend on. The control is inverted and some form of container sets the dependencies. Using IoC often leads to much cleaner code and provides an excellent way to de-couple dependent classes.

IOC in Spring:

IoC is a big part of what Spring does. It also offers a number of other capabilities apart from Dependency Injection(DI).

The core of Spring’s implementation is based on DI, although dependency lookup features are provided as well. When Spring automatically provides collaborators to a dependent object, it does so using DI. In a Spring-based application, it is always preferable to use dependency injection to pass collaborators to dependent objects rather than have the dependent objects obtain the collaborators via lookup. Although DI is the preferred mechanism for wiring together collaborators and dependent objects, you need dependency
lookup to access the dependent objects. In many environments, Spring cannot automatically wire up all of your application components using DI, and you must use dependency lookup to access the initial set of components. When you are building web applications using Spring’s MVC
support, Spring can avoid this by gluing your entire application together automatically. Wherever possible, you should use DI with Spring; otherwise, you can fall back on the dependency lookup capabilities.

Dependency Injection(DI) is provided by Core package in Spring Framework allowing you to manage bean container functionality. The basic principle is that beans define their dependencies (i.e. 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) of the bean instantiating or locating its dependencies on its own using direct construction of classes, or something like the Service Locator pattern.

An interesting feature of Spring’s IoC container is that it has the ability to act as an adaptor between its own dependency injection container and external dependency lookup containers.

Spring supports both constructor and setter injection and bolsters the standard IoC feature set with a whole host of useful additions to make your life easier.

Dependency Injection majorly in two forms:

1. Setter-based: Classes are typically JavaBeans, with a no-arg constructor, and with setters for the IoC container to use when wiring dependencies. This is the variant recommended by Spring. While Spring supports constructor-based injection, a large number of constructor arguments can be difficult to manage.


public interface Hello {

public String sayHello(String str);

public String showEmpDetails();
}

public class HelloImpl implements Hello{

private String greeting;
private EmployeeTO empTO;

public String sayHello(String str){
return greeting+" "+str;
}

public String showEmpDetails(){
return "Employee "+empTO.getName()+ " with empId = "+empTO.getId();
}

public String getGreeting() {
return greeting;
}

public void setGreeting(String greeting) {
System.out.println("Inside setGreeting");
this.greeting = greeting;
}

public void setEmpTO(EmployeeTO empTO) {
System.out.println("Inside setEmpTO");
this.empTO = empTO;
}

}

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<bean id="hello" class="bean_injection.HelloImpl">

<property name="greeting">
<value>Good Night!...</value>
</property>

<property name="empTO">
<ref local="employeeTO"/>
</property>

</bean>

<bean id="employeeTO" class="bean_injection.EmployeeTO">

<property name="id">
<value>1</value>
</property>

<property name="name">
<value>Prashant</value>
</property>

</bean>


</beans>




2. Constructor-based: Classes contain constructors with a number of arguments. The IoC container discovers and invokes the constructor based on the number of arguments and their object types. This approach guarantees that a bean is not created in an invalid state.


public interface Hello {

public String sayHello(String str);
}

public class HelloImpl implements Hello{

private String greeting;

public HelloImpl(){}

public HelloImpl(String str){
System.out.println("Inside constructor ");
this.greeting = str;
}

public String sayHello(String str){
return greeting+" "+str;
}

}

<beans>

<bean id="hello" class="bean_injection.HelloImpl">

<constructor-arg>
<value>Good Morning!...</value>
</constructor-arg>
</bean>

</beans>




Which one to use (Setter-based / Constructor-based)?

Constructor injection is particularly useful when you absolutely must have an instance of the dependency class before your component is used. Many containers, Spring included, provide a mechanism for ensuring that all dependencies are defined when you use setter injection, but by using constructor injection, you assert the requirement for the dependency in a container-agnostic manner.

Setter injection is useful in a variety of different cases. If you want the component to expose its dependencies to the container but provide its own defaults, setter injection is usually the best way to accomplish this. Another benefit of setter injection is that it allows dependencies to be declared on an interface, although this is not as useful as you might first think. Consider a typical business
interface with one business method, defineMeaningOfLife(). If, in addition to this method, you define a setter for injection such as setEncylopedia(), you are mandating that all implementations must use or at least be aware of the encyclopedia dependency. You do not need to define this setter at all—any decent IoC container, Spring included, can work with the component in terms of the
business interface but still provide the dependencies of the implementing class.

Benefits of Dependency Injection :

1. Unit testable
2. Dependencies are explicit
3. Consistent
4. Can wire up arbitrarily complicated graphs
5. You don’t need to write plumbing code
6. Pluggability
7. Reduces cost of programming to interfaces to zero

As described by Rod Johnson "Spring provides a factory to end all factories".

Hope it will be useful.

10 comments:

Prashant Jalasutram said...

Hi Sneha,

Nice recap of Dependency injection in Spring.

Thanks
Prashant
http://www.prashantaboutindia.blogspot.com/

Praveen said...

Great effort.

I have a few comments/questions about your section on 'Which one to use (Setter-based / Constructor-based)?'

I am not sure if I was able to follow

1. why constructor injection can not make us declare dependencies on a interface
2. how constructor injection can not make us provide our own defaults.

Please clarify

once again ...great effort ...keep up the good work

Vinay said...

great artical, nice to read about DI

R said...

Hi ..
what if I have multiple constructor w/ different args like

class a
{
a(int a , int b){}
a(string a , int a){}
a(string s,char c){}
}

how will i put them in xml files?
do I need t create different bean objects in xml files calling these different constructors?

sun moon and others said...

Thanks Sneha .... Your blog is very helpful for me ...

Bharat said...

Hi Sneha,

Nice article on "DI".....Very Helpfull.....

Thanks & Best Regards,
Prabudhabharat

manoj said...

Hi,

It is a very good article and useful as well. I want to know one thing that which type of dependency injection use in which condition. I mean when we will use Setter DI and constructor based Di.

Thanks
Manoj Tiwari

Java/J2ee said...

Nice,Great Work!

JVRCPRAVEEN said...

To add to your Blog

Basically Dependency Injection means
Don't call me, I'll call you." inversion of control(IoC) takes the responsibility for making things happen for you.

As you said your your blog we can eliminate Hardcoding of new keyword as we can mention the dependencies in xml file.

JVRCPRAVEEN said...

We can also use Interface based Dependency Injections.