1.Overview

In this article, we will explain concept of Inversion of control (IOC) and Dependency injection (DI) and ways to implement them in spring with simple, clear explanation.

2.Inversion of control (IOC) and Dependency injection (DI)

2.1 Inversion of control with Spring

Inversion of control (IOC) is widely used programing principle in which some part/portion of program is controlled by container (in case of spring framework, The IOC container).

Modularity:

Separation of functionality of program into distinct and independent units such that each unit has everything necessary to execute only one aspect of the desired functionality.

Principle use of IOC:

We can use IOC to increase modularity of program and in software terms, more modularity means more extensibility.

In sample way, assume you bought a car and initially you are driving car to company. after few months you reached to higher position.
Now you have a lot of work to do so, you appointed a driver to drive you to office so that you can continue your work while you are on the way.

IOC Simplified:

  1. Driving a car your self is same as program without inversion of control
  2. Driver is same as Container or Framework
  3. Instead of driving car yourself, you appointed driver. You gave control to driver. This is inversion of control.

We can ask container to inject dependencies by passing metadata to Spring IOC container.

 

spring-inversion-of-control

Spring Inversion of Control

 

2.1.1 Pros of Inversion of control (IOC)

  1. To decouple task execution from its implementation.
  2. To avoid side effects when replacing a module.
  3. Objects can be added and tested independently of other objects, because they don’t depend on anything other than what you pass them.

2.1.2 Ways to implement Inversion of Control(IOC) in Spring

Inversion of control (IOC) can be implemented by,

  1. factory pattern,
  2. service locator pattern
  3. dependency injection.

2.2 Dependency Injection in Spring

Dependency Injection is used to inject object dependencies when it requires. In simple way, instead of instantiating class dependency in same class, we will inject it at runtime. Through dependency injection, we can achieve loose coupling of objects.
If class A uses some functionalities of class B, then we can say, A is dependent on B. In order to call class B’s methods in class A, we have to create class B’s object in class A.

So, instead of creating class B object in class A at compile time, we can inject it on runtime through Dependency Injection.

Let’s make it clear by example,

Seller wants to notify customers about offers through SMS. Have look at following implementation without dependency injection.

Dependency Injection

package com.javadevloperzone.spring;
public class Seller {
  
  private SMSService sMSService;
  
  public Seller(){		
    this.sMSService=new SMSService();
  }
  
  public void notifyCustomer(String message,String phoneNumber){		
    sMSService.sendMessage(message,phoneNumber);
  }
  
}
package com.javadevloperzone.spring;
public class SMSService {
  
  public void sendMessage(String message,String phoneNumber){		
    //logic to send sms
  }
}

Description:
1. Seller class is tightly coupled to SMS Service class
2. Seller class has notifyCustomer() method

Now days WhatsApp became one of popular communication medium. Seller decided to inform customers through what’s up.

In this case we should modify Seller class like as follows,

package com.javadevloperzone.spring;
public class Seller {
  
  private WhatsUpService whatsUpService 
  
  public Seller(){		
    this.whatsUpService =new WhatsUpService ();
  }
  
  public void notifyCustomer(String message,String phoneNumber){		
    whatsUpService .sendMessage(message,phoneNumber);
  }
}
package com.javadevloperzone.spring;
public class WhatsUpService {
  
  public void sendMessage(String message,String phoneNumber){		
    //logic to send What's Up message
  }
}

Every time when seller wants to interact with customers through another medium, we have to change lot of code and testing also become difficult. It might be easier for few dependencies but in real world, there will be more objects have dependency on other objects

Have a look at following code implemented with Dependency injection and abstraction

package com.javadevloperzone.spring;
public class Seller {
  
  private IMessageService messageService;
  
  public Seller(IMessageService messageService){		
    this.messageService=messageService;
  }
  
  public void notifyCustomer(String message,String phoneNumber){		
    messageService.sendMessage(message,phoneNumber);
  }
}
package com.javadevloperzone.spring;
public interface IMessageService {
  public void sendMessage(String message,String phoneNumber);
}
package com.javadevloperzone.spring;
public class WhatsUpService implements IMessageService {
  
  @Override
  public void sendMessage(String message,String phoneNumber){		
    //logic to send What's Up message
  }
}

Now Seller class is loosely coupled to its dependency. So in this case the implementation is hidden from task execution.
In future, if Seller wants to change, he just needs to change IMessageService class implementation

2.2.1 Ways to implement dependency injection in spring

We can implement Dependency Injection with Spring framework in following ways,

  1. Setter Dependency Injection (SDI): by setter method we will inject dependencies
  2. Constructor Dependency Injection (CDI): by constructer arguments we will inject dependencies
  3. By auto wiring: if we use annotation @Autowired, spring will inject dependencies

Mostly used way of injecting dependencies in spring is by auto wiring objects like follows,

package com.javadevloperzone.spring;
@Component
public class Seller {
  
  @Autowired
  private IMessageService messageService;
        public void notifyCustomer(String message,String phoneNumber){		
    messageService.sendMessage(message,phoneNumber);
  }
}

4.Conclusion

In this article, we have presented concepts inversion of control and dependency Injection and their implementations in spring framework.
Hope you got clarity on these topics and You can read more about these concepts at,
https://en.wikipedia.org/wiki/Dependency_injection
https://en.wikipedia.org/wiki/Inversion_of_control

5.References

https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-introduction

Was this post helpful?

Leave a Reply

Your email address will not be published. Required fields are marked *