Spring Inversion of control with annotations

In this article, we will learn about spring inversion of control with annotations. We will also see a sample example which will help us to understand this topic more clearly.

What are java annotations?

  • Java annotations are special markers or labels that we add to the java classes.
  • Java annotations can be processed at compile time or run time depending on the retention policy.
  • Java annotations provide metadata about the class.

Note* Metadata is data about data.
Metadata example – Say a cell phone is a data
Metadata of Cell phone – Screen size, processor specification, camera specification, etc.

Annotation example

@FunctionalInterface annotation indicates to the compiler that an interface should not have more than one abstract method. If we add more than one abstract method to a class annotated with @FunctionalInterface annotation then the compiler will throw an exception.

@FunctionalInterface
public interface Addition {
  int sum(int a, int b);
  int subtract(int a, int b);
}

>> javac Addition.java

Output: Addition.java:1: error: Unexpected @FunctionalInterface annotation
Addition is not a functional interface
multiple non-overriding abstract methods found in interface Addition

If you want to understand the annotations in depth please check this article https://reflectoring.io/java-annotation-processing/

Why annotations?

Annotation minimizes the XML configuration. Say we are having 100 java classes and we have to register them with the spring container. To register all those beans with the container we will have to write them in the spring configuration file.

Writing 100 beans in a config file is a hectic task also we have to add the dependencies and properties in the configuration file which makes our work more complex. Hence making use of annotations will make our life easier.

Achieving spring inversion of control with annotations

We have to enable the component scanning in the spring config file. Once we add the component scanning feature, spring will scan our java classes for special annotations and spring will automatically register those beans in the spring container.

Enable the component scan

  • Firstly we have to add the below line in the spring configuration file.
<context:component-scan base-package="com.getinputs" />
  • Secondly we have to annotate the bean classes with @Component annotation.

Note* Spring will scan the classes annotated with @Component annotation that are available in com.getinputs base package.

Sample Example

We will create an interface that will have multiple implementations

package com.getinputs;

public interface Employee {
  void getWorkType();
  void getSalary();
}
  • Create a Manager class that implements the Employee interface and annotate the Manager class with @Component annotation
package com.getinputs;

import org.springframework.stereotype.Component;

@Component("manager")
public class Manager implements Employee {

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

  @Override
  public void getSalary() {
    System.out.println("Rs.50000");
  }
}
  • Create an Accountant class that implements the Employee interface and annotate the Accountant class with @Component annotation
package com.getinputs;

import org.springframework.stereotype.Component;

@Component("accountant")
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.40000");
  }
}
  • Create a configuration file and enable the component scanning
<?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">

   <context:component-scan base-package="com.getinputs" />
    
</beans>
  • Create an application context and call the methods of the spring bean
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 manager = context.getBean("manager", Employee.class);
    manager.getWorkType();
    manager.getSalary();

    Employee accountant = context.getBean("accountant", Employee.class);
    accountant.getWorkType();
    accountant.getSalary();

    context.close();
  }
}

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

From the above, we can see the spring has registered the Manager and Accountant beans and created an instance for them. Thus we are able to call the methods of that classes.

Default Bean Id

In the above example while creating a Manager class and an Accountant class we have annotated them and named the Component.

@Component("manager")
public class Manager

@Component("accountant")
public class Accountant

If we are using some other component name still it will work just we have to update the argument of the getBean method in the main class.

@Component("theManager")
public class Manager 

Employee manager = context.getBean("theManager", Employee.class);

Say we are not having any component name defined in the annotation then what will be the default bean id?

@Component
public class Manager

In this case, manager will be the default bean id.

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

If there are multiple words in the class name then
The first letter of the first word will be lowercase
The first letter of the next words will be in uppercase

@Component
public class AssistantDirector

In this case "assistantDirector" will be the default bean id. 

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

Manager -> manager
Accountant -> accountant
AssistantDirector -> assistantDirector
JuniorAssistantDirector -> juniorAssistantDirector

https://github.com/getinputs/samples/tree/main/annotation_component_scanning

So this is all about spring configuration with annotations. I hope you found this article interesting and valuable. If you are having any concerns or questions about this article please comment below and please share it to help me grow.

Leave a Comment