Dependency injection with annotation and autowiring

In this article, we will learn about dependency injection with annotation and autowiring. We will also see a sample example which will help us to understand this topic more clearly.

The process of injecting one bean into the other by the spring container is known as dependency injection. There are 3 ways to do the dependency injection

  • Constructor Injection
  • Setter Injection
  • Field Injection

In this article, we will concentrate on dependency injection using annotations and autowiring. To know more about dependency injection using XML configuration please refer to this article https://getinputs.com/spring-dependency-injection/

To understand this topic we should know what is Spring Autowiring.

What is spring autowiring?

Spring can automatically wire up our objects together for dependency injection. Spring will look for a class that matches the property by type. Ex. Interface or Class. If the type matches then spring will automatically inject the dependency else it will not. Hence it is known as autowiring. We will understand autowiring in more depth in the below example.

Example

Say we are having 2 beans Manager and Address bean. We have to inject Address dependency into the Manager bean.

Since we will be doing the dependency injection using annotation hence spring container should understand we are making use of annotations. So we have to enable the component scanning in the spring configuration file.

Spring container will look for all the component classes which are specially annotated in the base package and register them with the container.

<?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 Address class with @Component annotation

package com.getinputs;

import org.springframework.stereotype.Component;

@Component("address")
public class Address {

  public void getAddress() {
    System.out.println("Manager's address is : Civil lines , Delhi");
  }
}

Create an Employee interface so that we can use this interface for multiple implementations.

package com.getinputs;

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

Constructor injection

In constructor injection, the spring container will inject the dependency via a constructor.

  • Create a Manager class that implements Employee.
  • We will annotate the Manager class with @Component annotation.
  • We will autowire the Address bean here using constructor injection. We will use the @Autowired annotation to do this injection.
package com.getinputs;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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

  private Address address;

  @Autowired
  public Manager(Address address) {
    this.address = address;
  }

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

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

  @Override
  public void getAddress() {
    address.getAddress();
  }
}

Setter injection

In setter injection, the spring container will inject the dependency via setter methods.

  • Create a Manager class that implements Employee.
  • We will annotate the Manager class with @Component annotation.
  • We will autowire the Address bean here using setter injection. We will use the @Autowired annotation to do this injection.
package com.getinputs;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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

  private Address address;

  @Autowired
  public void setAddress(Address address) {
    this.address = address;
  }

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

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

  @Override
  public void getAddress() {
    address.getAddress();
  }
}

Field injection

In field injection, the spring container will inject the dependency via fields.

  • Create a Manager class that implements Employee.
  • We will annotate the Manager class with @Component annotation.
  • We will autowire the Address bean here using field injection. We will use the @Autowired annotation to do this injection.
package com.getinputs;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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

  @Autowired
  private Address address;

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

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

  @Override
  public void getAddress() {
    address.getAddress();
  }
}

Since the Address type will match the registered bean in all 3 types of injections hence the address dependency should get injected in manager bean.

Now we will create an application context and call the above manager bean methods to verify if dependency injection was done properly.

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("manager", Employee.class);
    employee.getWorkType();
    employee.getSalary();
    employee.getAddress();

    context.close();
  }
}

Output:
Manage all the employees
Salary is Rs.50000
Manager's address is : Civil lines , Delhi

As we are able to see the manager’s address in the above output so we can say that the dependency injection with annotation and autowiring was successful.

Constructor injection sample – https://github.com/getinputs/samples/tree/main/constructor-injection-annotations

Setter injection sample – https://github.com/getinputs/samples/tree/main/setter-injection-annotation

Field injection sample – https://github.com/getinputs/samples/tree/main/field-injection-annotation

So this is all about dependency injection with annotation and autowiring. 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