Home > Spring > Inversion of Control – Dependency Injection explained in simple terms

Inversion of Control – Dependency Injection explained in simple terms

Inversion of Control – Dependency Injection:

Instead of Object creating its dependencies, let container create and inject into Object. Control is being inverted from Object to Container.

Encapsulation says “The Caller should know its dependencies”

IOC  says “The Caller should know its dependency interfaces”

If the caller doesn’t know its dependencies and knows only interfaces, we can give any of the class to the Object.  Will explain with an example

Let’s Say we have a

package com.java2practice;
public class UsersListFromDB{
     public void printUsers(){
System.out.println(“printing users from database”);
     }
}

 

And UsersView to use the UsersListFromDB,

package com.java2practice;
public class UsersView{
 private UsersListFromDB userListFromDB = new UsersListFromDB();
 public void printUsers(){
      userListFromDB.printUsers();
 }
}

Now create a client program to access the UsersView.java

package com.java2practice;
public class UsersViewTest{
 public static void main(String[] args){
      UsersView usersView = new UsersView();
      usersView.printUsers();
 }
}

If we use like this, the object  UsersListFromDB is tightly coupled with UsersView. If we want to show UsersListFromExcel it won’t be possible.

For this we need to create an interface called

public interface UsersList{
       public void printUsers();
}

And make the UsersListFromDB, UsersListFromExcel implement the UsersList like below

public class UsersListFromDB implements UsersList{
       public void printUsers(){
System.out.println(“users list printing from database”);
       }
}

public class UsersListFromExcel implements UsersList{
       public void printUsers(){
System.out.println(“users list printing from excel”);
       }
}

Now we can change our UsersView class to

public class UsersView{
       private UsersList userList = new UsersListFromDB();
       public void printUsers(){
userList.printUsers();
       }
}

This concept is called interaface referencing. One of the object oriented principle Program to interface not program to class”

But still our problem is not solved, with out changing the UsersView we can not add UsersListFromExcel

Now We will try with Factory Design pattern

public class UsersFactory{
       public UsersList getUsersList(){
                 return new UsersListFromDB();
       }
}

In the UsersView.java we need to call this UsersFactory to get the appropriate object.

public UsersView{
       UsersList usersList = new UsersFactory().getUsersList();
       public void printUsers(){
usersList.printUsers();
       }
}

Now the client program will look like this


public class UsersViewTest{
       public static void main(String[] args){
              UsersView usersView = new UsersView();
              usersView.printUsers();
       }
}

This is more elegant and with out touching UsersView.java file we can switch to UsersListFromExcel  or UsersListFromDB by changing UsersFactory.

But still we need to change the UsersFactory.

With spring IOC our UsersView.java will look like this

public class UsersView{
       private UsersList usersList;
       public void setUsersList(UsersList usersList){
              this.usersList = usersList;
       }
       public void printUsers(){
             usersList.printUsers();
       }
}

That’s it, we don’t need to bother about instantiating the UsersList interface with its implemented classes.

To tell the container about our Java classes we need to write configuration file.

Bean-config.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-3.0.xsd">

      <bean id="usersListFromDB" class="com.java2practice.UsersListFromDB"/>
      <bean id="usersListFromExcel" class="com.java2practice.UsersListFromExcel/">
      <bean id="userView">
<property ref=” usersListFromDB” />
      </bean>
</beans>

We have to write our client program to use all these:

public class UesrsViewTest{
       public static void main(String[] args){
              ApplicationContext context = new ClassPathXmlApplicationContext("bean-config.xml");
              UsersView usersView = (UsersView)context.getBean(“userView”);
              usersView.printUsers();
       }
}

Here ApplicationContext will read the bean configuration file and accordingly it will inject the dependencies into the UsersView.java

When we are calling context.getBean(“userView”) it will return UsersView with dependencies injected into it.

If we want to use UsersListFromExcel, just we need to change in configuration file

Then the out put will be “printing users from excel file”

Categories: Spring
  1. September 23, 2012 at 3:38 pm

    Inversing of control from developer to an external program in order to create instances and assign references for our java objects is called Dependency injection.

    As a java developer, whatever we code [or write] is nothing but handling the control. Taking the control from main method, we move the control with our code in order to serve our requirement. Usually we ask the control to create some instances and invoke required methods on them. Deepening on our requirement we may ask it to hold the execution for some time or execute another set of instructions etc. which is called as threading mechanism. Let’s avoid discussing it here. The objective of IOC is to relieve the developer from the responsibility of creating the objects which makes our code tightly coupled.
    Simply to say, instead of creating objects from our code we ask another program to do that and assign the references to our variables. Whenever we are talking about the external program which is apart from our code, the best and easy way of communication to it is through XML files. This is grandly accepted practise in industry for many projects starting from small scale projects to large scale enterprise applications. Using XML files will avoid recompilation of the code which is preferably good news to the deployment team. Because we can’t anticipate all the consequences that arise once we re-build the system for some small modification.
    Here we are configuring an external program to create and inject [or assign] references to our objects. We can define this in an XML file.
    Finally what I wanna say is, Inversion of Control is a design pattern which allows us to have a provision to configure our system through some XML files for creating objects and assigning appropriate references.

    • rameshcharykotha
      September 23, 2012 at 3:41 pm

      Thanks Arun, your explanation is very clear…

  2. September 23, 2012 at 3:44 pm

    Glad for it dude….

  1. No trackbacks yet.

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 )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: