DI (Dependency Injection)
스프링이 다른 프레임워크와 차별화되어 제공하는 의존 관계 주입 기능으로, 객체를 직접 생성하는 게 아니라 외부에서 생성한 후 주입 시켜주는 방식이다.
DI (의존성 주입) 를 통해서 모듈 간의 결합도가 낮아지고 유연성이 높아진다.
첫번째 방법은 A객체가 B와 C객체를 New 생성자를 통해서 직접 생성하는 방법이고,
두번째 방법은 외부에서 생성된 객체를 setter()를 통해 사용하는 방법이다.
이러한 두번째 방식이 의존성 주입의 예시인데,
A객체에서 B, C객체를 사용(의존)할 때 A객체에서 직접 생성하는 것이 아니라 외부(IOC컨테이너)에서 생성된 B, C객체를 조립(주입)시켜 setter 혹은 생성자를 통해 사용하는 방식이다.
스프링에서는 객체를 Bean 이라고 부르며, 프로젝트가 실행될 때 사용자가 Bean 으로 관리하는 객체들의 생성과 소멸에 관련된 작업을 자동적으로 수행해주는데 객체가 생성되는 곳을 스프링에서는 Bean 컨테이너라고 부른다.
DI 는 IoC 를 구현하는 디자인 패턴이다.
의존성 주입에는 세 가지 주요 스타일이 있다.
생성자 주입 (Constructor Injection)
public class A {
private B b;
public A(B b) {
this.b = b;
}
}
Setter 주입 (Setter Injection)
public class A {
private B b;
public void setB(B b) {
this.b = b;
}
}
인터페이스 주입 (Interface Injection)
public interface BInjection {
void inject(B b);
}
public A implements BInjection {
private B b;
@Override
public void inject(B b) {
this.b = b;
}
}
어떤 의존성을 주입할 것인지 인터페이스에 명시하고, 의존성을 주입받는 클래스는 해당 인터페이스의 구현체로 만든다. setter 주입과 비슷하다.
DI 원칙으로 코드가 더 깔끔해지고, 객체에 의존성이 제공될 때 분리하는 것이 더 효과적이다.
객체는 의존성을 조회하지 않으며 의존성의 위치나 클래스를 알지 못한다. 결과적으로, 특히 의존성이 인터페이스 또는 추상 기본 클래스에 있는 경우 클래스를 테스트하기가 더 쉬워지며, 이를 통해 단위 테스트에서 스텁 또는 모의 구현을 사용할 수 있습니다.
IoC (Inversion of Control)
IoC 란 "제어의 역전" 이라는 의미로, 말 그대로 메소드나 객체의 호출작업을 개발자가 결정하는 것이 아니라, 외부에서 결정되는 것을 의미한다.
IoC 는 제어의 역전이라고 말하며, 간단히 말해 "제어의 흐름을 바꾼다" 라고 한다.
객체의 의존성을 역전시켜 객체 간의 결합도를 줄이고 유연한 코드를 작성할 수 있게 하여 가독성 및 코드 중복, 유지 보수를 편하게 할 수 있게 한다.
기존에는 다음과 같은 순서로 객체가 만들어지고 실행되었다.
하지만, 스프링에서는 다음과 같은 순서로 객체가 만들어지고 실행된다.
스프링이 모든 의존성 객체를 스프링이 실행될 때 다 만들어주고 필요한 곳에 주입시켜줌으로써 Bean들은 싱글턴 패턴의 특징을 가지며,
제어의 흐름을 사용자가 컨트롤하는 것이 아니라 스프링에게 맡겨 작업을 처리하게 된다.
원문 : https://velog.io/@gillog/Spring-DIDependency-Injection
https://velog.io/@ohzzi/Spring-DIIoC-IoC-DI-%EA%B7%B8%EA%B2%8C-%EB%AD%94%EB%8D%B0