Inversion of Control (IOC) and Dependency Injection in Spring Framework.

Laukikrupne
4 min readMar 15, 2021

--

Spring is an open source framework for building enterprise Java applications. Spring was created by Rod Johnson(2003) and released under Apache 2.0 license. Spring provides to create high performing, easily testable and reusable code.

Spring Framework enables Plain Old Java Object (POJO) based programming model, with POJO you don’t need EJB container product. Spring utilizes existing technologies like ORM frameworks, logging frameworks, JEE, Quartz, and JDK timers.

Spring is well-designed web model-view-controller (MVC) framework. Spring provides a coherent transaction management interface that be applicable to a local transactions() local transactions or global transactions(JTA). Spring provides a suitable API for translating technology-specific exceptions ( for instance, thrown by JDBC, Hibernate, or JDO,) into consistent, unchecked exceptions. The Inversion of Control (IoC) containers are lightweight, especially when compared to EJB containers. Being lightweight is beneficial for developing and deploying applications on computers with limited resources (RAM&CPU). Testing is simple because environment-dependent code is moved into this framework.

What are Beans ?

  • In Spring, POJO’s (plain old java object) are called ‘beans’ and those objects instantiated, managed, created by Spring IoC container.
  • Bean definition contains configuration metadata. With this information container knows how to create bean, beans lifecycle, beans dependencies.
  • After specifying objects of an application, instances of those objects will be reached by getBean() method.
  • Spring supports given scope types for beans ie. Singleton (a single instance per Spring IoC container (default)), Prototype, Request, Session, and Global-session.
Spring IOC high-level view.

The Spring IoC container makes use of Java POJO classes and configuration metadata to produce a fully configured and executable system or application.

What is Spring IoC ?

Spring IoC stands for Inversion of Control. IoC is based on hollywood principle : “Don’t call me, I’ll call you.”. In a nutshell … inversion of control is about: the responsibility of coordinating collaboration between dependent objects is transferred away from the objects themselves.

Traditional approach

In order to use object B, object A has to instantiate form Class B. In order to use object C, object B has to instantiated form Class C.

Problem with traditional approach

  • Classes are tightly coupled.
  • Hard to test: A <- B, B <- C.
  • Hard to reuse.
  • Hard to understand: cannot see the main flow.
  • Hard to maintain: fixing one bug may result creating more new bugs.
  • Utilizing interface will not solve the problem.

Components of Spring IoC

  • IoC is practiced using Dependency Injection.
  • Two forms of DI: Setter Injection and Constructor Injection.
  • Code are decoupled with interface.
  • Spring IoC container is the platform.
  • Bean factory produce beans.
  • Configuration file defines beans and the main flow.

Summarize Spring IoC

  • Decoupling with interface.
  • Configuration file defines the rules.
  • Objects are given rather than obtained.
  • More options in the configuration file. ie Inheritence between the beans, Singleton or non-singleton, and Abstract beans.
  • The Spring container glues everything together.

Dependency Injection (DI)

DI is only one concrete example of Inversion of Control. In a complex Java application, classes should be loosely coupled. This feature provides code reuse and independently testing classes. DI helps in gluing loosely coupled classes together and at the same time keeping them independent. Using dependency injection helps to see easily what the component dependencies are. DI is preferable because it makes testing easier.

Dependency Injection Types

  1. By passing parameters to the constructor (used for mandatory dependencies).
  2. By using setter methods(used for optional depenedencies).

Constructor based DI.

Constructor based DI occurs when the container invokes a class constructor with a number of arguments, each representing a dependency on other class.

Plane.java

public class Plane {

private RouteFinder routeChecker;

public Plane (RouteFinder routeChecker) {
System.out.println("Inside Plane Constructor");
this.routeChecker = routeChecker;
}

public void routeCheck() {
routeChecker.findRoute();
}
}

RouteFinder.java

public class RouteFinder {

public RouteFinder() {
System.out.println("Inside RouteFinder's constructor");
}
public void findRoute() {
System.out.println("Inside findRoute method in RouteFinder");
}
}

RouteTest.java

public class RouteTest {

public static void main(String[] args) {
Application context = new
ClassPathXmlApplicationContext("Beans.xml");

Plane rc = (Plane) context.getBean("plane");
rc.routeCheck();
}
}

Beans.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="plane" class="Plane">
<constructor-arg ref="route"/>
</bean>

<bean id="route" class="RouteFinder"></bean>
</beans>

Setter-based DI

RouteFinder.java

public class RouteFinder {

public RouteFinder() {
System.out.println("Inside RouteFinder's constructor");
}
public void findRoute() {
System.out.println("Inside findRoute method in RouteFinder");
}
}

Plane.java

public class Plane {

private RouteFinder routeChecker;

// a setter method to inject the dependency.
public void setRoute(RouteFinder routeChecker) {
System.out.println("Inside setRoute methon in Plane");
this.routeChecker = routeChecker;
}

// a getter method to return routeChecker
public RouteFinder getRoute() {
return routeChecker;
}

public void routeCheck() {
routeChecker.findRoute();
}
}

RouteTest.java

public class RouteTest {

public static void main(String[] args) {
Application context = new
ClassPathXmlApplicationContext("Beans.xml");

Plane rc = (Plane) context.getBean("plane");
rc.routeCheck();
}
}

Beans.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="plane" class="Plane">
<property name="route" ref="route"/>
</bean>

<bean id="route" class="RouteFinder"></bean>
</beans>

--

--

No responses yet