Ioc, DI, 컨테이너, 빈
IoC (Inversion of Control)
- 프로그램의 제어 흐름을 직접 제어하는 거이 아니라 외부에서 관리하는 것을 제어의 역전(IoC)라 한다.
- 프레임워크는 내가 작성한 코드를 제어하고, 대신 실행한다.
DI (Dependency Injection)
- 한 객체가 추상화에만 의존할 수 있도록 어떤 구현체에 의존할 지는 AppConfig 같은 외부 클래스에서 결정하고 의존관계를 주입함
- 의존 관계는 정적인 클래스 의존 관계와, 실행 시점에 결정되는 동적인 객체(인스턴스) 의존 관계를 구분해서 생각해야함
- 외부에서 실제 구현 객체를 생성하고 클라이언트에 전달해서 실제 의존관계가 연결 되는 것을 의존관계 주입이라 한다.
- 의존관계 주입을 사용하면 정적 의존 관계를 변경하지 않고, 동적 의존 관계를 변경할 수 있다.
IoC 컨테이너, DI 컨테이너
- 의존관계 주입을 대신 해주는 것을 DI 컨테이너(혹은 Ioc 컨테이너)라고함
- 스프링을 사용하면 DI 컨테이너 = Ioc 컨테이너 = 스프링 컨테이너
스프링 빈
- 스프링 컨테이너에서 관리하는 객체를 스프링 빈(Bean)이라고 한다.
- 빈 이름은 항상 다른 이름을 부여해야 한다.
스프링 빈 등록 및 컨테이너 생성
@Bean을 이용해 빈을 등록할 수 있다.
@Configuration
public class AppConfig {
// 빈 이름은 기본적으로 메소드 이름으로 등록됨
@Bean
public MemberService memberService(){
// 생성자를 통해 구현 객체 주입 - 생성자 주입
return new MemberServiceImpl(memberRepository());
}
}
ApplicationContext가 컨테이너가 된다.
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
AnnotationConfigApplicationContext 은 ApplicationContext의 구현체로, 자바 파일로 컨테이너를 생성한다. (xml을 이용하는 구현체도 있음)
빈 조회
빈 이름과 타입으로 조회할 수 있다.
// ("빈 이름으로 조회")
MemberService memberService = ac.getBean("memberService", MemberService.class);
// ("이름 없이 타입으로만 조회")
MemberService memberService = ac.getBean(MemberService.class);
// ("구체 타입으로 조회")
MemberService memberService = ac.getBean("memberService", MemberServiceImpl.class);
타입으로 조회했을 때, 두 개 이상의 빈이 나와 오류가 날 수 있다.
자식타입이 있을 경우, 자식 타입의 빈도 모두 나옴.
그럴때는 이름을 지정하여 조회하자.
특정 타입의 빈을 모두 조회하는 코드
Map<String, MemberRepository> beansOfType = ac.getBeansOfType(MemberRepository.class);
for (String key : beansOfType.keySet()) {
System.out.println("key = " + key + " value = " + beansOfType.get(key));
}
System.out.println("beansOfType = " + beansOfType);
컨테이너의 모든 빈을 조회하는 코드
String[] beanDefinitionNames = ac.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
Object bean = ac.getBean(beanDefinitionName);
System.out.println("name = " + beanDefinitionName + " object = " + bean);
}
애플리케이션 빈을 모두 조회하는 코드
String[] beanDefinitionNames = ac.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
Object bean = ac.getBean(beanDefinitionName);
System.out.println("name = " + beanDefinitionName + " object = " + bean);
}
reference : 인프런 김영한 강사님 스프링핵심원리
'개발 > Spring' 카테고리의 다른 글
[스프링] 스프링 핵심원리 - 의존관계 자동주입 (0) | 2021.12.06 |
---|---|
[스프링] 스프링 핵심원리 - 싱글톤 컨테이너 (0) | 2021.12.06 |
[JPA] 변경감지(dirty checking)와 병합(merge) (0) | 2021.09.06 |
[JPA] 도메인 및 웹 계층 개발 (0) | 2021.09.06 |
[JPA] 도메인 분석 설계 및 아키텍처 (0) | 2021.09.06 |
댓글