Spring inversion of control

Inversion of control is an approach to outsourcing the construction and management of objects. This outsourcing will be handled by the Spring container object factory.

In other words, we can say Instead of us as a developer creating the objects we give the responsibility to Spring container to create and manage the objects for us.

Why Inversion of control?

Handling the life cycle of an object is a complex task. We as a developer have to keep track of object creation and also we have to manage them. So instead of us doing it, we will hand over this responsibility to Spring and we will focus mainly on business usage.

Also, Spring says

  • The application should be configurable.
  • We should easily switch between the implementation types.

Without inversion of control

Normal java applications cannot be made configurable. We will try to understand this with an example.

In a company, we are having a Manager we want to know the type of work and salary of the Manager.

package com.getinputs;

public class Manager {

  void getWorkType() {
    System.out.println("Manage all the employees");
  }

  void getSalary() {
    System.out.println("Rs.500000");
  }
}

package com.getinputs;

public class Demo {

  public static void main(String[] args) {
    Manager manager = new Manager();
    manager.getWorkType();
    manager.getSalary();
  }
}

Output: Manage all the employees
Rs.500000

The above code will work with the Manager object only. Now say we are having different categories of employees like Accountant, Clerk, etc and we want to get the work type and salaries of them.

We will be doing the best practice and we will make use of a generic interface.

package com.getinputs;

public interface Employee {
  void getWorkType();
  void getSalary();
}

package com.getinputs;

public class Manager implements Employee {

  @Override
  public void getWorkType() {
    System.out.println("Manage all the employees");
  }

  @Override
  public void getSalary() {
    System.out.println("Rs.500000");
  }
}

package com.getinputs;

public class Accountant implements Employee {

  @Override
  public void getWorkType() {
    System.out.println("Does all the accounting work");
  }

  @Override
  public void getSalary() {
    System.out.println("Rs.400000");
  }
}

package com.getinputs;

public class Demo {

  public static void main(String[] args) {

    Employee manager = new Manager();
    manager.getWorkType();
    manager.getSalary();

    Employee accountant = new Accountant();
    accountant.getWorkType();
    accountant.getSalary();
  }
}

Output: Manage all the employees
Rs.500000
Does all the accounting work
Rs.400000

In the above example, we have made a provision to easily switch between the implementation types but the application is still not configurable. Here Spring inversion of control feature comes into the picture.

Achieving Spring inversion of control

We can achieve Spring inversion of control using Object factory. We can have our application talk to spring and ask spring to give us an object based on the configuration file or annotation. Spring will give us an appropriate implementation. Thus we can say that the application is configurable.

There are 3 ways to configure the spring container:

  • XML configuration file
  • Java annotations
  • Java source code

As we just have to understand Spring inversion of control so we will make use of XML configuration as part of this article.

Let us understand this better with an example.

The steps required to create a sample spring application are:

To configure the spring beans

In the applicationContext.xml configuration file, we will configure a spring bean.

applicationContext.xml

<beans>
 <bean id="employee" class="com.getinputs.Manager"></bean>
</beans>

id: This is an alias name that we can use in java code to retrieve the bean from the spring container.

class: Fully qualified name of an implementation class whose object we need.

Creating a spring container

Spring container is generally known as application context.

This ApplicationContext is implemented in multiple ways. The most common ways are:

  • ClassPathXmlApplicationContext: To read the XML configuration from the classpath.
  • AnnotationConfigApplicationContext: To read the annotated classes as configuration.
  • GenericWebApplicationContext: It is suitable for web applications.

We will read an XML configuration file from the classpath of an application below:

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

We have to use the name of the configuration file in the argument of the ClassPathXmlApplicationContext constructor.

In the applicationContext.xml file, we have configured the spring beans.

Note* We can use any configuration file name but it should be consistent.

Retrieving the beans from the container

Now our application will talk to spring container and ask to provide a manager bean. Now based on the configuration in the XML file, spring will create a com.getinputs.Manager object and provide it to the application.

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

Employee employee = context.getBean("employee", Employee.class);

The employee is the same bean id in the configuration file. We have to make sure it is an exact match.

Employee.class is the interface that is implemented by com.getinputs.Manager class.

Below is the complete codebase for the configuration file and main class

applicationContext.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" 
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- Define your beans here -->
    <bean id="employee" class="com.getinputs.Manager"></bean>
</beans>
package com.getinputs;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringDemoApp {
  public static void main(String[] args) {

    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

    Employee employee = context.getBean("employee", Employee.class);
    employee.getWorkType();
    employee.getSalary();
    context.close();
  }
}

Output: Manage all the employees
Rs.500000

Now if we want to get the Accountant bean so we will update the configuration file instead of the source code. Thus we can say the application is configurable.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- Define your beans here -->
    <bean id="employee" class="com.getinputs.Accountant"></bean>
</beans>
package com.getinputs;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringDemoApp {

  public static void main(String[] args) {

    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

    Employee employee = context.getBean("employee", Employee.class);
    employee.getWorkType();
    employee.getSalary();
    context.close();
  }
}

Output: Does all the accounting work
Rs.400000

Thus using spring inversion of control We can easily switch between the implementation types also we have made the application configurable.

https://github.com/getinputs/samples/tree/main/inversion-of-control

This is all about spring inversion of control. I hope you found this article interesting and valuable. If you are having any concerns or questions about this article please comment below.

Leave a Comment