# Dependency and Dependency Injection explained in simple words

When I first started learning Spring Boot, everyone kept talking about **Dependency Injection (DI)**. Most tutorials immediately jumped into `@Autowired`, `@Service`, and Spring Containers, which made the concept feel more complicated than it really is.

So let's forget Spring Boot for 2 minutes and understand the core idea first.

## What Is a Dependency?

A dependency is simply **something a class needs to do its job**.

Consider this example:

```java
public class Car {

    private Engine engine;

    public Car() {
        this.engine = new Engine();
    }
}
```

Here, `Engine` is a dependency of `Car`.

Why?

Because a car needs an engine to function. Without an engine, the car cannot do its job.

You can think of it like this:

*   Car = Main object
    
*   Engine = Dependency
    

## What Is Dependency Injection?

Dependency Injection means:

> It is a design pattern where instead of creating the dependency yourself, someone else provides it to you.

Let's compare both approaches.

## Without Dependency Injection

```java
public class Car {

    private Engine engine;

    public Car() {
        this.engine = new Engine();
    }
}
```

In this case, the `Car` class creates its own engine.

The responsibility of creating the dependency belongs to the `Car`.

### What Happens?

```java
Car car = new Car();
```

Internally:

```java
Engine engine = new Engine();
```

is created by the `Car` itself.

## With Dependency Injection

```java
public class Car {

    private Engine engine;

    public Car(Engine engine) {
        this.engine = engine;
    }
}
```

Notice something important:

The `Car` no longer creates the engine.

Instead, the engine is supplied from outside.

### Someone Else Creates the Engine

```java
Engine engine = new Engine();

Car car = new Car(engine);
```

The engine is now being **injected** into the car.

## Breaking Down the Name

The term "Dependency Injection" sounds intimidating, but it's actually very simple.

### Dependency

Something a class needs.

```java
Engine
```

### Injection

Providing that dependency from outside.

```java
new Car(engine);
```

So:

```java
new Car(engine);
```

is Dependency Injection because the dependency (`engine`) is supplied externally rather than created inside the class.

Instead of creating objects manually, we use beans in spring that makes it easy to work with different objects. Please read this article, if you want to know about the [basics of beans.](https://saroj-dev.hashnode.dev/learn-basics-of-spring-beans-with-java-configuration)

## The Problem with Tight Coupling

When the `Car` creates its own `Engine`, the two classes become **tightly coupled**.

```java
public class Car {

    private Engine engine;

    public Car() {
        this.engine = new Engine();
    }
}
```

Now imagine we later create another type of engine.

```java
public class ElectricEngine {
}
```

Suppose we want our car to use an `ElectricEngine` instead of an `Engine`.

With the current design, we have to modify the `Car` class itself.

```java
public Car() {
    this.engine = new ElectricEngine();
}
```

Every time the dependency changes, the `Car` class must also change.

This makes the code harder to maintain and extend.

In other words, the `Car` is **tightly coupled** to a specific implementation of `Engine`.

## How Dependency Injection Solves This

Instead of deciding which engine to create, the `Car` simply accepts one from outside.

```java
public class Car {

    private Engine engine;

    public Car(Engine engine) {
        this.engine = engine;
    }
}
```

Now someone else decides which engine to provide.

```java
Engine engine = new Engine();

Car car = new Car(engine);
```

The `Car` no longer cares **how** the `Engine` was created—it only cares that it receives one.

This makes the code more flexible because the responsibility of creating the dependency is moved outside the `Car` class.

## Two Common Ways to Inject Dependencies

There are two common ways to inject a dependency into a class:

*   Constructor Injection
    
*   Setter Injection
    

### 1\. Constructor Injection

The dependency is provided when the object is created.

```java
public class Car {

    private Engine engine;

    public Car(Engine engine) {
        this.engine = engine;
    }
}
```

Usage:

```java
Engine engine = new Engine();

Car car = new Car(engine);
```

Since the dependency is passed through the constructor, the `Car` object always has an `Engine` when it is created.

* * *

### 2\. Setter Injection

The dependency is provided after the object has been created.

```java
public class Car {

    private Engine engine;

    public void setEngine(Engine engine) {
        this.engine = engine;
    }
}
```

Usage:

```java
Engine engine = new Engine();

Car car = new Car();

car.setEngine(engine);
```

Here, the `Car` is created first, and the dependency is injected later using a setter method.

* * *

In Spring Boot, both constructor injection and setter injection are supported. However, **constructor injection is generally preferred** because it ensures all required dependencies are available when the object is created and makes the class easier to test.
