IoC (제어의 역전)
Inversion of Control (제어의 역전)
- 이전 강의에서 작성한 코드는, Order Entity가 사용할 클래스를 결정하고 해당 클래스의 객체를 생성함
- 모든 종류의 작업을 사용하는 쪽에서 제어를 하는 구조
- IoC = 제어의 역전 : 이런 제어의 흐름의 역전 되는것을 의미
- 객체가 자신이 사용할 개체를 스스로 선택하지 않고 스스로 생성도 하지 않는다.
- 라이브러리를 사용하는 어플리케이션 코드는 애플리케이션 흐름을 직접 제어하지만, 프레임워크 기반 어플리케이션에서는 어플리케이션 코드가 프레임워크에 의해서 사용된다.
- 프레임워크가 흐름을 주도하면서 개발자가 만든 어플리케이션 코드를 사용함
- 즉, 어플리케이션 코드는 프레임워크가 짜놓은 틀에서 수동적으로 동작한다.
- The Hollywood Principle 이라고도 한다 (직접 호출하지 말고, 프레임워크가 호출할 때까지 기다려라)
OrdeContext 애플리케이션의 주요 객체 생성과 관계설정을 담당하는 클래스
OrderService Order에 대한 비즈니스 로직을 담는 클래스
- 이전시간에 작성한 코드에 위 두가지 클래스를 추가해보자.

- OrderConctext : 주문에 대한 전반적인 도메인 객체의 생성과, 객체간 의존관계 설정을 책임진다
- OrderService : 직접 어떤 Repo를 사용할지 선택하지 않았고, VoucherService도 직접 생성하지 않았다
- 객체 생성 제어권을 OrderContext 에 넘김
- OrderContext에서 OrderRepo와 VoucherService 객체를 만든 다음, 이를 다시 OderService에 전달해줌으로써 객체간의 의존관계를 설정해 주었다.
- IoC가 발생했다.
- 이렇게 IoC가 일어나는 공간을 IoC 컨테이너라 한다
- IoC 컨테이너는 객체의 생성과 파괴 그리고 개별 객체간의 의존관계 설정을 관장한다.
- 프레임워크, 컨테이너, 컨텍스트 등
DDD(Domain Driven Design)

Aggregate
- 일종의 Entity 또는 Entity들의 집합으로, 각각의 aggregate는 루트를 가진다. (루트 역시 하나의 Entity)
- 하나의 aggregate 단위로 트랜잭션이 보장되어야 한다(ACID원칙)
- 서비스는 마치 Utility class 처럼 상태가 없고, 행위(method)만 존재한다.
- Repository = Entity를 저장하는 저장소
- Repository에 저장된 데이터(Entity)와 서비스의 행위를 통해 Aggregate가 하나의 트랜잭션처럼 구성됨
Application Context

Register
- IoC 컨테이너에 어떠한 객체를 사용할 것임을 등록하는(알려주는) 것
- IoC는 객체 정보를 Register 받으면, 객체에 대한 인스턴스를 만들어 주고 그 생명주기를 관리한다.
Application Context
- 스프링에서는 이런 IoC컨테이너를 ApplicationContext 인터페이스를 통해 제공한다.

- ApplicationContext는 BeanFactory를 상속한다.
- BeanFactory 내부를 살펴보면 객체 생성, 조합, 의존관계 설정에 필요한 여러 요소들을 확인할 수 있다.
- Bean : Spring의 ApplicationContext, BeanFactory, IoC Container등에 의해 관리되어지는 객체
- Java와 스프링을 코드를 작성하면 여러 객체들이 JVM 위에 올라가는데, 이 때 IoC에 의해 관리되는 객체와 그렇지 않은 객체를 구별하기 위해 Bean 이라는 개념을 도입
- Annotation을 이용해서 객체를 Bean으로 지정해줄 수 있다.

Configuration Metadata
- ApplicaitonContext 는 만들어야할 Bean 에 대한 정보를 Configuration Metadata(설정 메타데이터) 로부터 받아온다.
- 이 메타데이터를 이용해 IoC 컨테이너에 의해 관리되는 객체들을 생성하고 구성함
- 즉, 메타데이터는 어플리케이션에서 사용되는 객체들의 도면/설계도 라고 볼 수 있다.
- Configuration Metadata는 XML 기반 또는 Java 파일 기반으로 작성할 수 있다.
- XML 기반으로 작성하는 경우 : GenericXmlApplicationContext 를 구현체를 사용
- Java 파일 기반으로 작성하는 경우 : AnnotationConfigApplicationContext 구현체를 사용
@Configuration
Annotation을 이용해서 Java Class를 메타데이터로 지정할 수 있다.AnnotationConfigApplicationContext
놀랍게도 클래스 이름이다.구현체란?
ApplicationContext 인터페이스를 implement 받아서 구체화 한 것
Dependency Injection
Dependency Injection
- IoC는 다양한 방법으로 만들 수 있다.
- 전략 패턴, 서비스 로케이터 패턴, 팩토리 패턴, 의존관계 주입 패턴 등
- 지금까지 코드에서 Order가 어떠한 Voucher 객체를 생성할지, OrderService가 어떤 OrderRepository 객체를 생성할지 스스로 결정하지 않고 생성자를 통해 객체를 주입받는 패턴을 이용했다.
- 이를 생성자 주입 패턴(Dependency Injection) 이라고 부른다.
- 그 외에도 스프링은 Setter 기반의 의존관계 주입도 지원한다.