> For the complete documentation index, see [llms.txt](https://yihyuns-gitbook.gitbook.io/today-i-learned/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yihyuns-gitbook.gitbook.io/today-i-learned/spring/di.md).

# DI (Dependency Injection, 의존성 주입)

> #### Spring Framework의 핵심 개념 3가지
>
> 소스 코드의 복잡도를 줄이고, 효율을 높이고, 유지보수를 용이하게 하기 위해 Spring에서는 다음의 3가지를 이용한다.
>
> 1. **DI**
> 2. [IoC Container](/today-i-learned/spring/ioc_container.md)
> 3. [AOP](/today-i-learned/spring/aop.md)

## DI의 정의

의존성 주입이라는 말 그대로, 객체 간 연결을 위해 한 객체 내에서 다른 객체를 생성하는 방식이 아닌 `주입하는 방식`으로 이용하는 기법

## DI의 장점

### 결합력이 높은 코드의 문제점

다음과 같은 코드를 결합력이 높은 코드라고 본다.

```java
class A {
	
	B1 b1;

	public A() {
		b1 = new B1();
	}

}

class B1 {

}

class B2 {

}
```

만약 B1을 나중에 개발한 B2로 교체하고자 한다면 B1 인스턴스를 생성하는 모든 소스 코드를 수정해주어야 한다.

따라서 결합력이 높은 코드는 다음의 문제를 발생시킨다고 볼 수 있다.

1. 소스 코드의 일부를 수정하고자 할 때, 연관된 모든 부분을 수정해야 한다. 이는 복잡하고 위험한 일이 될 것이다.
2. 해당 객체를 필요로 하는 모든 클래스 내에서 new를 통해 새 인스턴스를 생성하게 된다면, 너무 많은 인스턴스를 생성하게 됨

### DI를 통한 해결

DI를 이용한 코드는 다음과 같다.

```java
class A {
	
	B b;

	public A(B b) {
		this.b = b;
	}

}

interface B {

}

class B1 implements B {

}

class B2 implements B {

}
```

이제 B1을 B2로 교체하고자 한다 해도 A를 수정할 필요가 없게 되었다.

따라서, DI는 위에서 명시한 문제를 다음과 같이 해결한다.

1. 소스 코드의 일부(B1)를 수정하고자 하면 해당 부분만 수정하면 된다.
2. B 관련 인스턴스는 한 번만 생성되어 여러 객체에 주입되어 사용될 수 있다. (싱글톤 가능)
