IoC, DI, 컨테이너
제어의 역전(IoC)
- 기존 프로그램은 구현 객체가 필요한 서버 객체를 생성하고, 연결하고, 실행했다. -> 프로그램의 제어의 흐름을 조종
- AppConfig를 사용하여 구현 객체는 자신의 로직만 실행
- 프로그램이 제어흐름을 하는 것이 아닌 외부에서 관리하는 것을 **제어의 역전(IoC)**라고 한다.
프레임워크 vs 라이브러리
- 프레임워크 : 내가 작성한 코드를 제어하고, 대신 실행
- 라이브러리 : 내가 작성한 코드가 직접 제어의 흐름을 진행
DI
- 의존관계는 정적인 클래스, 실행 시점에 결정되는 동적 객체를 분리하여 생각
- 정적인 클래스 : import 코드만 보고 쉽게 판단 가능, 하지만 실제 어떤 객체가 주입 될지는 모름
- 의존관계 주입 : 실행시점에서 외부(AppConfig)에서 구현 객체를 생성하고 클라이언트에 전달
컨테이너
- AppConfig와 같이 의존관계를 연결해주는 것을 IoC컨테이너 또는 DI컨테이너라고 한다.
정리
의존관계 주입을 통하여 클래스 의존관계를 변경하지 않고(코드를 변경하지 않고) 동적인 객체 인스턴스 의존관계를 쉽게 변경할 수 있다.
스프링 컨테이너
- xml으로 만들 수 있고, 애노테이션 기반으로 생성 가능
-
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
- 스프링 컨테이너를 선언하기 위해서는 class를 인자로 넣어줘야한다.
- 스프링 컨테이너 안에 스프링빈을 등록한다. **bean 이름은 항상 다른 이름을 부여해줘야한다.
- (스프링컨테이너 안에 스프링 빈들이 존재)
- 스프링 컨테이너는 빈을 등록하면서 의존관계를 주입한다.
- bean 조회
-
ac.getBeanDefinitionNames() : 스프링에 등록된 모든 빈 이름을 조회한다. ac.getBean() : 빈 이름으로 빈 객체(인스턴스)를 조회한다. ac.getBean("userService", UserSerivce.class) : 빈 이름으로 조회한다. ac.getBean(UserService.class) : 타입으로 조회한다. **동일한 타입이 있을 경우 이름으로 조회를 해주어야한다. ac.getBeansOfType(UserRepository.class) : 특정 타입 모두 조회 빈은 부모를 조회하면 자식 클래스가 모두 조회된다.
**참고
인프런 - 스프링 핵심 원리 - 기본편(김영한)