1- 제어의 역전 : IoC ( Inversion of Control)
- 말 그대로 제어의 역전
- 내가 무언가를 호출하는게 아니라 프레임워크가 대신 호출하는 것을 말함
- 스프링에만 극한된 개념이 아니라 여러 곳에서 나옴
- AppConfig 등장 이후 구현 객체는 자신의 로직을 실행하는 역할만 담당함
제어 흐름 자체를 AppConfig가 가져감 - 코드 예시
@Override
public Order createOrder(Long memberId, String itemName, int itemPrice) {
// IoC에 의하면 OrderServiceImpl은 memberRepository에 대한 제어권이 없음
Member member = memberRepository.findById(memberId);
int discountPrice = discountPolicy.discount(member, itemPrice);
return new Order(member.getId(), itemName, itemPrice, discountPrice);
}
2- 프레임워크 vs 라이브러리
- 프레임워크: JUnit
- 개발자는 테스트 코드를 쫙 작성해.
- 우리는 로직만 딱 작성을 하는데, JUnit에서 본인만의 라이프 사이클 속에서 로직을 실행함
- 예시로, @BeforeEach 어노테이션이 올라가있는 메서드가 있다면 그것을 먼저 실행하고 실행하고자 했던 메서드가 실행된다는 등
- 한 마디로 라이프사이클에서 내가 만든 로직이 콜백식으로 실행됨 - 라이브러리
- 내가 작성한 코드가 제어 흐름을 담당하는 것
3- 의존관계 주입 : DI ( Dependency Injection )
- OrderServiceImpl은 DiscountPolicy 인터페이스에만 의존함. 고로 실제 어떤 구현체가 사용되는지 모름>
- 의존관계는 정적인 클래스 의존 관계와 실행 시점에 결정되는 동적인 객체(인스턴스) 의존 관계를 분리해 생각해야 함
- 정적인 클래스 의존관계
- 산출물: 클래스 다이어그램
- 클래스가 사용하는 import 코드만 보고 의존관계 쉽게 판단 가능
- 주문 발생시 어떤 역할들이 요구되어 설계되었는지 판단 가능함
- 요점을 한 문장으로 정리하자면, 정적인 의존관계는 애플리케이션을 실행하지 않아도 분석 가능함
- 허나 의존관계만으로는 어떤 구현체가 주입되는지 알 수 없음 - 동적인 객체 의존관계
- 산출물: 객체 다이어그램
- 어플리케이션 실행 시점에서 생성된 객체 인스턴스의 참조가 연결된 의존 관계
- 의존관계 주입: 애플리케이션 실행 시점(런타임)에 외부에서 실제 구현 객체를 생성하고, 클라이언트에 전달해 클라이언트와 서버의 실제 의존관계가 연결되는 것
- 객체 인스턴스를 생성하고 참조값을 전달해 연결됨
- 의존관계 주입을 사용하면 클라이언트 코드를 변경하지 않고, 클라이언트 호출 대상의 타입 인스턴스 변경 가능
(클라이언트 코드 변경 없이 구현체 변경 가능하다는 뜻)
- 의존관계 주입을 사용하면 정적인 클래스 의존관계 변경 없이 동적인 객체 의존관계 변경 가능
한 마디로, 기존 정적인 클래스 다이어그램의 구조를 변경하지 않고 ( == 애플리케이션 코드를 건드리지 않고 ) 구현체만
변경할 수 있음
3- IoC 컨테이너, DI 컨테이너
- AppConfig 처럼 객체를 생성하고 관리해 의존관계를 연결해주는 것은 'IoC 컨테이너' 또는 'DI 컨테이너'
- 아에 DI 컨테이너가 좀 더 정확한 용어임.
IoC의 핵심은 제어권이 역전. 즉, 넘어가있다는 것기에 너무 범용적인 용어임.
그래서 후대에 특성에 맞게 DI 컨테이너로 이름을 바꿈. - AppConfig 코드를 보면 OrderServiceImpl을 생성할 때, 생성자 파라미터로 넘어가는 멤버 리파지터리와 할인 정책을 생성하여 집어넣어줌.
--> 이런 것을 DI 컨테이너라 함. - AppConfig에 대해 용어가 많음
- 전체의 조립을 하는 역할을 함.
- 그래서 어셈블러 혹은 오브젝트 팩토리 등으로 불리기도 함
'Development > Spring Boot' 카테고리의 다른 글
[Spring Boot] 스프링 컨테이너와 스프링 빈 (0) - 이전 강의 중요 포인트 정리 (0) | 2022.08.13 |
---|---|
[Spring Boot] 스프링 부트로 전환하기 (0) | 2022.08.09 |
[Spring Boot] 새로운 구조 및 구현체 적용 (0) | 2022.08.04 |
[Spring Boot] AppConfig 리팩토링 (0) | 2022.08.04 |
[Spring Boot] 스프링 핵심 원리 이해 - 객체 지향 원리 적용 (1) 관심사의 분리 (0) | 2022.08.02 |