VOOZH about

URL: https://www.geeksforgeeks.org/system-design/dependency-injection-di-design-pattern/

โ‡ฑ Java Dependency Injection (DI) Design Pattern - GeeksforGeeks


  • Courses
  • Tutorials
  • Interview Prep

Java Dependency Injection (DI) Design Pattern

Last Updated : 21 May, 2026

Dependency Injection (DI) is a design pattern in which an object receives the required objects (dependencies) from an external source instead of creating them itself.

  • DI helps reduce tight coupling between classes
  • Improves code reusability and testability.
  • Widely used in enterprise Java applications

Example: A Car class may require an Engine object to work. Instead of creating the Engine inside the Car class using new Engine(), the Engine object is provided externally by a framework such as Spring.

Dependency Between Classes

A dependency is an object that another object requires to perform its work.

๐Ÿ‘ jd-1

The diagram explains:

  • A class may use functionality provided by another class
  • The class being used is called a dependency
  • Direct object creation can lead to tight coupling
  • Changes in one implementation may affect multiple classes
  • Dependency Injection helps manage dependencies efficiently

Tight Coupling Problem

Without Dependency Injection

Problems with This Approach

  • Car is tightly coupled to LegacyEngine
  • Difficult to replace the engine implementation
  • Code changes are required in multiple places
  • Harder to test and maintain
  • Less flexible design

Suppose a new engine model is introduced.

Now the Car class must be modified manually.

magine hundreds of classes using the old engine implementation. Updating all these classes manually becomes difficult and time-consuming. This is the problem that Dependency Injection solves.

Dependency Injection and Inversion of Control

๐Ÿ‘ file
Dependency Injection and Inversion of Control

Dependency Injection

Dependency Injection provides the required dependency object from an external source instead of creating it manually inside the class.

Instead of:

Engine engine = new DieselEngine();

The dependency is injected externally.

Inversion of Control (IoC)

Inversion of Control is a principle in which the responsibility of creating and managing objects is transferred from the application code to a framework or container.

In Spring:

  • The IoC Container creates objects
  • Manages dependencies
  • Injects required dependencies automatically

This reduces manual object creation and improves loose coupling.

Example of Dependency Injection Design Patterns in Java

Problem Statement

A vehicle such as a Car depends on multiple components like:

  • Engine
  • Headlights
  • Brakes

These components are called dependencies. Instead of creating these dependencies manually inside the class, Dependency Injection provides them externally using frameworks such as Spring.

๐Ÿ‘ jd-4

These components can be considered as your dependencies. Without any of these dependencies, our car can never be considered as a complete entity.

  • The left side represents multiple dependencies required by an application.
  • The โ€œEngineโ€ acts as a dependency used by different vehicle classes.
  • The โ€œExternal Agentโ€ represents the Spring Framework or IoC Container.
  • The framework injects the required dependency into classes like Car, Bike, and Scooter.
  • This reduces tight coupling and makes the code more reusable and maintainable

Step by Step Implementation for the above Problem

In the below solution we will understand above problem using code:

Real-world problem that occurs with Java Dependency Injection Design Pattern

๐Ÿ‘ jd-5

Step 1: Create the Dependency Interface

Define a common interface for all engine types.

  • Helps achieve loose coupling
  • Supports multiple engine implementations
  • Improves flexibility

Step 2: Create Dependency Implementation

Create a concrete implementation of the Engine interface.

Legacy Engine

New Engine

Step 3: Inject Dependency Using Constructor Injection

Step 4: Use Different Implementations

Step 5. Run Application

Output

New Engine Started
Car is Running

Now the Car class does not depend on a specific engine implementation. The same dependency can be reused across:

  • Car
  • Bike
  • Scooter

without modifying their source code.

๐Ÿ‘ jd-6

Dependency Injection Using Spring Framework

Spring Framework provides automatic dependency management using the IoC Container.

The framework:

  • Creates dependency objects
  • Manages object lifecycle
  • Injects required dependencies automatically

Step 6: Create Configuration Class

Use Spring Framework to manage dependencies.

  • @Configuration marks the configuration class
  • @Bean creates and manages dependency objects

Step 7: Inject Dependency into Car Class

Use @Autowired to inject dependency automatically.

  • Spring injects dependencies automatically
  • No manual object creation required
  • Supports loose coupling

Step 8: Reuse Dependency in Other Classes

The same dependency can be injected into other vehicle classes.

  • Same dependency reused across multiple classes.
  • Reduces duplicate code changes.

Bike class:

Scooter class:

Step 9: Add Spring Dependency in pom.xml

  • Adds Spring MVC support to the project.
  • Provides annotations like @Autowired and @Bean

pom.xml:

Step 7: Run the Spring Boot Application

When the application starts, the Spring IoC Container:

  • Creates the Engine object
  • Injects it into the Car class
  • Executes the drive() method

Main Class

Output

New Engine Started
Car is Running

Comment

Explore