728x90
DI (Dependency Injection) 의존관계 주입
- 의존관계 주입이란, 클래스의 연관 관계를 주입해주는 것이다.
- 의존관계는 정적인 클래스 의존관계와 실행 시점에 결정되는 동적인 객체(인스턴스) 의존관계 둘을 분리해서 생각해야한다.
- 애플리케이션 실행 시점(런타임)에 외부에서 실제 구현 객체를 생성하고 클라이언트에 전달해서 클라이언트와 서버의 실제 의존관계가 연결 되는 것을 의존관계 주입이라 한다.
- 의존관계 주입을 사용하면 클라이언트 코드를 변경하지 않고, 클라이언트가 호출하는 대상의 타입 인스턴스를 변경할 수 있다.
- DI(Dependency Injection)란, 스프링이 다른 프레임워크와 차별화되어 제공한는 의존관계 주입 기능으로, 객체를 직접 생성하는 것이 아니라 외부에서 생성한 후 주입 시켜주는 방식이다.
- DI(의존 관계 주입 or 의존성 주입)를 통해서 모듈 간의 결합도가 낮아지고 유연성이 높아진다.
🔍 의존관계 주입하는 방법
- 생성자 주입 (Constructor Injection)
- 세터 주입 (Setter Injection)
- 필드 주입 (Field Injection)
- 생성자 주입은, 객체가 생성되는 시점에 의존성이 주입되는 것이다.
- 세터 주입은, 객체의 set Method 호출되는 시점에 의존성이 주입되는 것이다.
- 필드 주입은, 객체의 인스턴스 필드에 의존성이 주입되는 것이다.
- setter injection은 한번에 한개의 의존관계를 주입 받을 수 있습니다.
- constructor injection을 하면 여러개의 의존관계를 주입 받을 수 있습니다.
💡 생성자 주입 방식이 제일 안전하다.
- 단일 책임의 원칙(SRP)을 지키기 쉽다. → 한눈에 해당 객체에 대한 의존관계와 복잡도를 알 수 있다.
- 테스트가 용이하다. → DI컨테이너를 사용하지 않고도 인스턴스화 할 수 있고, 다른 DI 프레임워크로 쉽게 바꿀 수 있다.
- Immutablity → 객체의 불변성(final)을 보장할 수 있다.
- 순환 의존성 → 생성자 주입에서는 객체가 서로 순환 의존성을 가질 경우 BeanCurrentlyCreationException이 발생한다.
보통 RunTime에 마구잡이로 set Method를 통해서 객체를 건드리는 습관은 좋지 않다.
이 경우 NullPointerException이 발생하거나, 예상치 못하는 버그가 발생할 확률이 정말 높기 때문이다.
그렇기 때문에 객체의 멤버변수는 항상 불변객체(final)로 해주는 습관이 좋다.
- A객체에서 직접 생성하는 것이 아니라 외부(IoC컨테이너)에서 생성된 외부 객체를 조립(주입)시켜 사용하는 방법이다.
- 스프링에서는 객체를 Bean이라고 부른다.
- 프로젝트가 실행될 때 사용자가 Bean으로 관리하는 객체들의 생성과 소멸에 관련된 작업을 자동적으로 수행해주는데 객체가 생성되는 곳을 스프링에서는 Bean 컨테이너라고 부른다.
IoC (Inversion of Control) 제어의 역전
- 프로그램의 제어 흐름을 직접 제어하는 것이 아니라 외부에서 관리하는 것을 제어의 역전(IoC)라고 한다.
- 스프링을 쓰기 전에는 개발자가 프로그램의 흐름을 제어하는 주체였다. 스프링에서는 프로그램의 흐름을 프레임워크가 주도하게 된다.
- 객체의 생성 ~ 생명주기 관리를 컨테이너가 도맡아서 하게 된다. 즉, 제어권이 컨테이너로 넘어가게 되고, 이것을 제어권의 흐름을 바뀌었다고 하여 제어의 역전(IoC)라고 부른다.
- 제어권이 컨테이너로 넘어옴으로써 DI(의존성 주입), AOP(관점 지향 프로그래밍)등이 가능하다.
- 프레임워크에서 제어의 권한을 넘김으로써 클라이언트 코드가 신경 써야 할 것을 줄이는 전략이다.
- 제어를 역전시키는(프레임워크가 나의 코드를 호출 할 수 있게 하는) 가장 쉽게 생각할 수 있는 접근 방법은 프레임워크의 event, delegate 에 나의 메소드를 등록 시키는 것이다. 전달되는 인자와 형식만 일치하면 프레임워크 코드는 내가 작성한 객체와 타입을 고려하지 않는다.
IoC 컨테이너, DI 컨테이너
객체를 생성하고 관리하면서 의존관계를 연결해 주는 것을 IoC컨테이너 또는 DI컨테이너라고 한다.
728x90
'[ Spring ] > Spring 핵심 원리' 카테고리의 다른 글
[Spring] @Configuration (0) | 2022.02.28 |
---|---|
[Spring] 싱글톤(Singleton) (0) | 2022.02.24 |
[Spring] 스프링 컨테이너와 스프링 빈 (0) | 2022.02.23 |
[Spring] 프레임 워크 vs 라이브러리 (0) | 2022.02.23 |
[Spring] 좋은 객체 지향 설계의 5가지 원칙(SOLID) (0) | 2022.02.18 |