Spring Inversion Control Mechanism

ยท

7 min read

Spring is a popular Java framework which will be useful in creating MVC web applications and REST API for the applications. But the real power of the spring framework comes from its inversion control and dependency injection mechanisms.

This blog will be focused on introduction to spring and inversion control for spring.

To understand Spring and Inversion Control, there are certain prerequisites.

Prerequisites:

  1. Core Java (Java EE would be really helpful before Spring )

  2. Object Oriented Programming Concepts

  3. Any Build Tool (optional)

What is Spring?

From the official docs of Spring ,

Spring Framework is a Java platform or framework that provides comprehensive infrastructure support for developing Java applications. Spring handles the infrastructure so you can focus on your application.

Now what does it mean ?

Suppose if we are writing java classes for a project , we need to create objects for this to use the class methods and properties. What if someone can create objects for us and we only need to focus on business logic. That someone is Spring.

Let's walk over it with an example of Mobile phones.

For Instance , we wanted to create mobile phone objects. Below are the java codes for Mobile interface , Redmi class , RealMe class and Manufacture class.

// Mobile Interface
public interface Mobile {
    public void message();
    public void call();
}

The above code is a Mobile Interface which will have two methods message() and call().

// redmi class
public class Redmi implements Mobile{
    @Override
    public void message() {
        System.out.println("Texting from redmi phone");
    }
    @Override
    public void call() {
        System.out.println("calling from redmi phone");
    }
}

Now , this is the redmi class which implements the Mobile interface and will override the methods in Mobile.

// realme class
public class Realme implements Mobile{
    @Override
    public void message() {
        System.out.println("Texting from realme phone");
    }
    @Override
    public void call() {
        System.out.println("calling  from realme phone");
    }
}

This is similar to Redmi class but for the Realme phones. Now we need a Implementation for both classes.

// Manufacture class
public class Manufacture {
    public static void main(String[] args) {
        Mobile mobile = new Redmi();
        mobile.message();
        mobile.call();
    }
}

This is our implementation class and we are creating a redmi object and referencing it with the Mobile Interface (Runtime Polymorphism). When compile and running, the output of this will be the methods of redmi class.

output for the code

Now , if I wanted to change from redmi to realme , I need to change the source code of the Manaufacture class like this:

Mobile mobile = new Realme();

// Manufacture class
public class Manufacture {
    public static void main(String[] args) {
        Mobile mobile = new Realme();
        mobile.message();
        mobile.call();
    }
}

The output for the above code will be like this:

For two classes , changing object might be fine. But for many classes, we cannot change the source code of Implementation each time.

So how can we implement this without changing the source code?

Need for Spring

We know , we need to change class instances each time we need newer instances, but what if there is someone who creates the object for us and we just need to use that object whenever we need?

This is achieved using Spring.

In the above example , we create objects for the implementation and the control of the creation is with us , But Using spring framework , it will create and manage objects for us. Now the control is with spring. For doing this, The Spring Container is also termed as **IOC Container (**Inversion of Control).

To be more precise , here is a visual representation of the spring way of creating an object.

This is a higher order overview of Spring Framework.

  1. POJOs: These are the classes which we use for business logic. In the above example , Realme and Redmi classes are the business logic classes. These classes will be included in the spring container for creating the objects.

  2. Spring Container: Spring Container manages the POJO classes (realme and redmi ) and creates objects for us. When the objects are inside the Spring container , it is termed as Beans.

    Beans: Any Java Object that is managed by the Spring container is called as Beans.

  3. configuration Metadata: Though Spring manages the classes , how does it do it? how does it know these are the classes that needs to be managed in the container?

    To allow this , we write instructions (configurations) to tell the container about the classes that needs to be managed.

    We can write this as XML Based Configuration as well as annotations.

IOC Container

All the business classes will be managed in spring IOC container. Now to create this spring container , java provides two interfaces.

  1. BeanFactory

  2. ApplicationContext

Here , we will be using ApplicationContext since it has more features than Bean Factory.

Since ApplicationContext is an interface , we need a class which implements it.And for XML configuration , the preferred class would be ClassPathXMLApplicationContext.

Implementation with Spring FrameWork

Let's consider the same examples of Mobiles as above, but this time with spring framework. Code for Redmi class and Realme class will be same.

But the implementation class will not manually create objects for these classes , instead we use Spring's xml based configuration for managing objects.

<?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.xsd">

    <bean id= "mobile" class= "com.anand.ioc.Realme">
    </bean>
</beans>

This is our xml configuration file that we need to have to specify the spring how to manage objects.

Since , Every object that is managed by Spring is a bean, we need to define the <bean></bean> definition , which will be inside <beans></beans> tag.

The bean tag in the above xml has two attributes.

  1. id: id is the reference that a bean will hold in the xml file. This reference is used to get the object in the manufacture class given below.

  2. class: Here , we will specify which class to use in the manufacture class.

    com.anand.ioc is a package and Realme is a class. As implemented ,we need to specify the fully qualified name in the class attribute.

Manufacture class is where we define the Spring Container and use objects.

package com.anand.ioc;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Manufacture {
    public static void main(String[] args) {
        // create the spring container and configure with config.xml
        ApplicationContext context = new ClassPathXmlApplicationContext("config.xml");
        // get the instance of bean and reference it to a class
        Mobile mobile = context.getBean("mobile" , Mobile.class);
        mobile.call();
        mobile.message();
    }
}

This is the Manufacture class which will create and manage objects for us.

Explanation of Spring Manufacture class

ApplicationContext context = new ClassPathXmlApplicationContext("config.xml");

This line is responsible for creating and managing objects inside the spring container.

ApplicationContext: It's an interface used to represent a spring container and is responsible for instantiating, configuring, and assembling the beans.

ClassPathXmlApplicationContext : Since ApplicationContext is a interface , we need a class which implements ApplicationContext. One such class is ClassPathXmlApplicationContext. In the above example , this class is taking config.xml as argument. This is the name of the xml configuration file where we defined beans for the classes.

Now we just need to get the beans from the container . To do this we use getBean() method which takes two parameters.

context.getBean("mobile" , Mobile.class)

Remember , we specified id = "mobile" in the xml file for reference?

The first parameter is referencing the id attribute in the xml file specifying the object of the class we need.

Second parameter is needed to typecast to the required class object. In our case , its Mobile.class.

That's it! Then we just need to use this reference to call methods in the object.

mobile.call(); , mobile.message();

output will be as guessed!

Now , if we want redmi object , we dont need to change the java code , we can specify com.anand.ioc.Redmi instead of com.anand.ioc.Realme in the xml file.

Comparing both Java and Spring based implementation ,

In Java , we need to create objects each time and the control of managing objects will be with us. But , Using Spring , we don't want to manually create object , instead Spring's IOC container will be used to create and manage objects.

Thus Spring will be in control for creation and managing of objects. This reverse of control from manual process to spring control is termed as Inversion of Control (IOC).

That's all from this article.

Hope this is helpful and thanks for reading..cheers!๐Ÿšฃ๐Ÿ˜Š

ย