DI, IoC
DI
DI는 의존 관계를 외부에서 결정(주입)해주는 것을 말한다. 스프링에서는 이러한 DI를 담당하는 DI 컨테이너가 존재한다. 이 DI 컨테이너가 객체들 간의 의존 관계를 주입한다.
의존 관계 주입 방법
- 생성자 주입
- 생성자 호출시점에 딱 1번만 호출되는 것이 보장된다.
- 불변, 필수 의존관계에 사용한다.
- setter 주입
- 필드 주입
의존 관계 주입을 사용해야하는 이유
- 재사용성을 높여준다.
- 테스트 하기에 용이하다.(내부에서 주입을 하지 않고 외부에서 주입을 하면 본인이 원하는 주입을 외부에서 만들어 넣은 후에 테스트 할 수 있다.)
- 객체간의 결합도가 낮추기 때문에 변경에 민감하지 않고 유연성과 확장성을 향상 시킬 수 있다.
IoC
- 프로그램의 제어 흐름을 직접 제어하는 것이 아니라, 외부에서 관리하는 것
- 객체의 생성과 소멸, 그리고 객체간의 의존관계를 설정하는 행위
- 모두 프레임워크가 대신 해준다 : 주도권이 역전됨 → 제어의 역전
- 프레임워크가 흐름을 주도하면서 개발자가 만든 어플리케이션 코드를 사용한다.
- 이렇게 IoC가 일어나는 공간을
IoC 컨테이너
라고 부른다.
@Component와 @Bean의 차이
- 선언 위치의 차이
- @Bean은 메서드 레벨에서 선언하며, 반환되는 객체를 개발자가 수동으로 빈으로 등록하는 애노테이션입니다.
- @Component는 클래스 레벨에서 선언함으로써 스프링이 런타임시에 컴포넌트스캔을 하여 자동으로 빈을 찾고 등록하는 애노테이션입니다.
- 사용 용도의 차이
- @Bean은 개발자가 컨트롤이 불가능한 외부 라이브러리들을 Bean으로 등록하고 싶은 경우에 사용합니다.
- @Component는 개발자가 컨트롤이 가능한 클래스에서 사용합니다.
Application Context란?
Spring에서는 빈의 생성과 관계설정 같은 제어를 담당하는 IoC 컨테이너인 빈 팩토리가 존재한다.
하지만 실제로는 빈의 생성과 관계설정 외의 추가적인 기능이 필요한데, 이러한 이유로 Spring에서는 빈 팩토리를 상속받아 확장한 애플리케이션 컨텍스트를 주로 사용한다.
애플리케이션 컨텍스트는 별도의 설정 정보를 참고하고 IoC를 적용하여 빈의 생성, 관계설정 등의 제어 작업을 총괄한다. 애플리케이션 컨텍스트에는 직접 오브젝트를 생성하고 맺어주는 코드가 없고, 그런 생성 정보와 연관관계 정보에 대한 설정을 읽어 처리한다. 예를 들어 @Configuration과 같은 어노테이션이 대표적인 IoC의 설정정보이다.
Application Context vs Bean Factory
Bean Factory의 확장버전 = Application Context
위 사진 처럼 Application Context는 Bean Factory의 기능인 빈의 생성, 관계설정, 조회만 하는 것이 아닌 다양한 기능을 한다.
MessageSource
- 들어오는 나라에 따라 한국어, 영어 등의 언어별로 출력 기능(국제화)
EnvironmentCapable
- 실제 개발을 할 때에는 크게 3가지 환경이 존재하는데 이런 환경들 마다 환경 변수를 설정하고, 서로 다른 DB나 외부 클라우드 연결을 달리할 수 있음(3가지 환경 = 로컬, 개발, 운영)
ApplicationEventPublisher
- 이벤트를 발행하고 구독하는 모델을 편리하게 지원
ResourceLoader
- 파일, 클래스패스, 외부 등에서 리소스를 편리하게 조회 가능
로딩 시점
- BeanFactory
- 빈을 사용하는 시점에서 빈을 로딩시킨다.(Lazy loading)
- 빈을 사용할 때 로딩하기 때문에 경량 컨테이너라고 부른다.
- ApplicationContext
- 모든 빈을 로딩하고 사용하다.(Eager loading)
- 빈을 모두 로딩하고 사용하기 때문에 무거운 컨테이너라고 한다.