codingstuff.io
ExploreTutorialsProblemsCS Subjects
Get Started
ExploreTutorialsProblemsCS Subjects
Get Started
codingstuff.io

Master the art of building software through interactive tutorials, real-world problems, and guided projects.

Pune, Maharashtra, India

codingstuffmail@gmail.com

Product

  • Explore
  • Tutorials
  • Problems
  • CS Subjects

Company

  • About
  • Contact
  • Privacy Policy
  • Terms & Conditions
  • Sitemap

© 2026 codingstuff.io. All rights reserved.

Built with ❤️ for developers everywhere

/
/
All Tutorials
🍃

Spring Boot

10 / 62 topics
9Components and Beans in Spring Boot10Dependency Injection with Autowiring
Tutorials/Spring Boot/Dependency Injection with Autowiring
🍃Spring Boot

Dependency Injection with Autowiring

Updated 2026-04-20
4 min read

Dependency Injection with Autowiring

Introduction

Dependency Injection (DI) is a design pattern that allows you to manage object dependencies externally, promoting loose coupling and making your code more testable. In the context of Spring Boot, DI is facilitated by the Spring Framework's powerful IoC (Inversion of Control) container. This tutorial will guide you through the fundamentals of Dependency Injection with Autowiring in Spring Boot, including real-world examples and best practices.

Understanding Dependency Injection

What is Dependency Injection?

Dependency Injection is a design pattern where an object receives its dependencies from external sources rather than creating them internally. This decouples the creation of objects from their usage, making the code more modular and easier to test.

Types of Dependency Injection

  1. Constructor Injection: Dependencies are provided through the constructor.
  2. Setter Injection: Dependencies are provided via setter methods.
  3. Field Injection: Dependencies are injected directly into fields (not recommended for production code).

Autowiring in Spring Boot

Spring Boot simplifies the process of dependency injection with its autowiring feature, which automatically resolves and injects dependencies.

How Autowiring Works

Autowiring is the mechanism by which Spring manages object dependencies. When a bean is created, Spring scans the application context for other beans that match the required type or name and injects them into the dependent bean.

Types of Autowiring Modes

  1. ByType: Spring resolves the dependency based on the data type.
  2. ByName: Spring resolves the dependency based on the bean name.
  3. Constructor: Similar to constructor injection, but uses autowiring.
  4. No: No autowiring is applied; you must manually wire dependencies.

Setting Up a Spring Boot Project

Before diving into DI and Autowiring, let's set up a basic Spring Boot project.

Step 1: Create a New Spring Boot Project

You can create a new Spring Boot project using Spring Initializr (https://start.spring.io/). Choose the following options:

  • Project: Maven Project
  • Language: Java
  • Spring Boot: Latest stable version
  • Project Metadata:
    • Group: com.example
    • Artifact: dependency-injection-demo
    • Name: Dependency Injection Demo
    • Description: A simple Spring Boot application demonstrating Dependency Injection
    • Package name: com.example.dependencyinjectiondemo
  • Packaging: Jar
  • Java: 11 or later

Add the following dependencies:

  • Spring Web

Click "Generate" to download the project zip file. Extract it and import it into your favorite IDE (e.g., IntelliJ IDEA, Eclipse).

Step 2: Create a Simple Service

Create a new package com.example.dependencyinjectiondemo.service and add a simple service class.

package com.example.dependencyinjectiondemo.service;

import org.springframework.stereotype.Service;

@Service
public class GreetingService {

    public String greet(String name) {
        return "Hello, " + name + "!";
    }
}

Step 3: Create a Controller

Create a new package com.example.dependencyinjectiondemo.controller and add a controller that uses the GreetingService.

package com.example.dependencyinjectiondemo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.example.dependencyinjectiondemo.service.GreetingService;

@RestController
public class GreetingController {

    private final GreetingService greetingService;

    @Autowired
    public GreetingController(GreetingService greetingService) {
        this.greetingService = greetingService;
    }

    @GetMapping("/greet")
    public String greet(@RequestParam(value = "name", defaultValue = "World") String name) {
        return greetingService.greet(name);
    }
}

Explanation

  • @Service: Marks the GreetingService class as a Spring-managed bean.
  • @RestController: Marks the GreetingController class as a REST controller.
  • @Autowired: Injects the GreetingService bean into the GreetingController.

Best Practices for Dependency Injection

  1. Prefer Constructor Injection: It promotes immutability and makes dependencies explicit.
  2. Use Field Injection Sparingly: It can lead to tight coupling and is harder to test.
  3. Avoid Overuse of Autowiring: Explicitly declare dependencies where possible.
  4. Use Qualifiers for Ambiguity Resolution: When multiple beans of the same type exist, use @Qualifier to specify which bean to inject.

Example with Qualifiers

Suppose you have two implementations of a service:

package com.example.dependencyinjectiondemo.service;

import org.springframework.stereotype.Service;

@Service
public class FormalGreetingService implements GreetingService {

    @Override
    public String greet(String name) {
        return "Good day, " + name + ".";
    }
}

And another implementation:

package com.example.dependencyinjectiondemo.service;

import org.springframework.stereotype.Service;

@Service
public class InformalGreetingService implements GreetingService {

    @Override
    public String greet(String name) {
        return "Hey, " + name + "!";
    }
}

To resolve the ambiguity, use @Qualifier:

package com.example.dependencyinjectiondemo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.example.dependencyinjectiondemo.service.GreetingService;

@RestController
public class GreetingController {

    private final GreetingService greetingService;

    @Autowired
    public GreetingController(@Qualifier("formalGreetingService") GreetingService greetingService) {
        this.greetingService = greetingService;
    }

    @GetMapping("/greet")
    public String greet(@RequestParam(value = "name", defaultValue = "World") String name) {
        return greetingService.greet(name);
    }
}

Testing with Dependency Injection

Testing is crucial when using DI. Spring Boot provides excellent support for testing with its @SpringBootTest annotation.

Example Test Case

Create a test class in the com.example.dependencyinjectiondemo package:

package com.example.dependencyinjectiondemo;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class GreetingControllerTests {

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void testGreetEndpoint() {
        String response = this.restTemplate.getForObject("/greet?name=John", String.class);
        assertThat(response).isEqualTo("Hello, John!");
    }
}

Explanation

  • @SpringBootTest: Loads the full application context.
  • TestRestTemplate: A convenient way to test REST controllers.

Conclusion

Dependency Injection with Autowiring is a powerful feature in Spring Boot that promotes clean, maintainable code. By following best practices and understanding how autowiring works, you can build robust applications that are easy to test and extend. This tutorial has covered the basics of DI, autowiring, and best practices, along with real-world examples to illustrate these concepts.


PreviousComponents and Beans in Spring BootNext Creating RESTful Controllers

Recommended Gear

Components and Beans in Spring BootCreating RESTful Controllers