예전에 어떤 시니어 분이 공유해준 글(참고자료)을 나에게 맞게 쉽게 정리해봤다.
평소 겉으로 알고 있던 개념이지만, 이번 기회에 조금 더 명확히 이해할 수 있었다.
IoC(Inversion of Control, 제어 역전)
전통적인 방식에 반대되는 흐름으로 코드가 진행되는 것을 말하는 일반적인 용어이다.
IoC를 설명하는 단골 예시는 바로 라이브러리와 프레임워크이다.
라이브러리는 내 코드가 라이브러리 코드(외부 코드)를 호출하지만,
프레임워크는 프레임워크(외부 코드)가 내 코드를 호출한다.
→ IoC는 프레임워크의 일반적인 특성이다.
Dependency Inversion Principle(DIP, 의존성 역전 원리)
의존관계를 갖는 인스턴스의 구성이 추상화에 의존하는 것을 뜻한다.
다음과 같이 인스턴스 간에 의존한다고 할 때,
의존 주체 인스턴스 → 의존 대상 인스턴스
의존 주체 인스턴스가 의존 대상 인스턴스(ex. 클래스)를 직접 생성한다면,
의존 대상 코드의 형식이 의존 주체 코드에 의해 결정되기 때문에 의존 대상 코드의 다형성이 동작하기 어렵다. (전통적 흐름)
반면 DIP가 사용되면 의존 관계가 추상화(ex. 인터페이스)에 의해 런타임에 결정되기 때문에 다형성을 적극적으로 활용할 수 있다. (전통적 흐름의 역전)
의존 주체가 의존 대상에 대한 의존성을 직접 정하는 것이 아닌 외부 주입에 의해 수동적으로 정하게 되기 때문에 의존성 '역전'이라는 표현 을 사용한 것 같다.
Dependency Injection(DI, 의존성 주입)
DIP를 구현하는 기법 중 하나이다.
의존 주체 인스턴스에 public하게 노출된 정보를 통해 의존 대상 인스턴스가 제공된다.
Constructor Injection(생성자 주입)
DI 중 가장 많이 사용되는 방법이다.
의존 주체의 생성자 매개변수로 의존 대상이 주입된다.
의존 주체가 생성됨과 동시에 의존성이 해결되고 의존 관계가 변하지 않는다. (불변)
의존성이 해결되지 않으면 의존 주체를 생성할 수 없기 때문에 의존성이 누락될 위험을 컴파일러로 차단할 수 있다. (누락)
Property Injection(속성 주입)
setter를 통해 의존성을 주입하는 방법이다.
속성이 외부에 노출된 정보를 의미하는지, 의존 대상을 의미하는지 별도의 설명이 없으면 구분하기 어렵다.
속성 설정은 의존 주체가 생성된 후에 진행되기 때문에 의존 주체는 필요한 의존성이 해결되지 않은 상태일 수 있다.
IoC Container
DIP가 적용된 모듈의 조립을 도와주는 도구이다.
IoC Container를 사용하지 않아도 생성자를 직접 호출함으로써 DIP를 보장받을 수 있지만,
IoC Container를 사용하면 생성자를 직접 호출하지 않고 컨테이너에 이미 DI가 되어 있는 인스턴스들을 가져다가 사용하면 된다.
또한 Container의 장점으로 인스턴스들의 수명을 관리할 수 있다는 점이 있다.
예를 들어, HTTP 서버의 경우 싱글톤 객체를 사용할 수도 있지만,
요청마다 각각 의존 대상 인스턴스를 만들고 요청에 대한 응답이 완료되면 인스턴스를 삭제하는 생명주기를 지정할 수도 있다.
Service Locator
DI와는 다른 DIP 구현법이다.
DI에서 의존 주체는 의존성을 외부의 주입에 의해 수동적으로 해결하는 반면,
ServiceLocator를 사용하는 의존 주체는 의존성이 필요한 시점에 능동적으로 의존성을 ServiceLocator에 요청한다.
ServiceLocator는 의존 주체가 매개변수가 없는 기본 생성자를 통해 생성되어야 하는 제약조건이 있거나,
의존 대상이 준비되기 전에 의존 주체가 만들어져야 하는 경우 등에 사용될 수 있다.
참고자료
https://justhackem.wordpress.com/2016/05/13/dependency-inversion-terms/
'java > spring' 카테고리의 다른 글
[Spring] DTO의 사용 범위 (0) | 2023.06.27 |
---|---|
[Spring] Service - 인터페이스 도입과 버저닝 (0) | 2023.06.26 |
[Spring] @TransactionalEventListener에서 예외가 발생하지 않는 이슈 (2) | 2023.06.23 |
[Spring] 스프링 디렉터리 패키지 구조 (0) | 2023.06.22 |
[Spring] Spring Data JPA의 페이징 (2) | 2023.06.21 |