[Spring] Section 4. 스프링 컨테이너와 스프링 빈
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
ApplicationContext를 스프링 컨테이너라 한다.
ApplicationContext는 인터페이스이다.
컨테이너에 있는 모든 빈을 조회해보자.
public class ApplicationContextInfoTest {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
@Test
@DisplayName("모든 빈 출력")
void findAllBean() {
String[] beanDefinitionNames = ac.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
Object bean = ac.getBean(beanDefinitionName);
System.out.println(beanDefinitionName + " object =" + bean);
}
}
@Test
@DisplayName("어플리케이션 빈 출력")
void findApplicationBean() {
String[] beanDefinitionNames = ac.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);
if(beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) {
Object bean = ac.getBean(beanDefinitionName);
System.out.println(beanDefinitionName + " object =" + bean);
}
}
}
}
ac.getBean(beanDefinitionName): 빈 이름으로 빈 객체 조회 (Object 타입의 bean)
* ac.getBeanDefinitionNames() : 스프링에 등록된 모든 빈 이름 조회
getRole() 로 구분
ROLE_APPLICATION : 일반적으로 사용자가 정의한 빈
ROLE_INFRASTRUCTURE : 스프링이 내부에서 사용하는 빈
타입으로조회
ac.getBeansOfType(): 해당 타입의 모든 빈 조회
타입으로 조회 시, 같은 타입의 스프링 빈이 둘 이상이면 오류 발생 => 빈 이름 지정하기
상속 관계
부모 타입으로 조회 => 자식 타입도 함께 조회
ex) Object 타입(모든 자바 객체의 최고 부모)으로 조회 => 모든 스프링 빈 조회
모든 자바 객체의 최고 부모 타입인 Object타입으로 스프링 빈을 조회하면, 모든 스프링 빈을 조회한다.
부모 타입으로 조회하면, 자식 타입도 함께 조회한다.
class ApplicationContextExtendsFindTest{
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(TestConfig.class);
@Test
@DisplayName("부모 타입 조회시, 자식이 둘 이상 있으면 중복 오류 발생")
void findBeanByParentTypeDuplicate(){
assertThrows(NoUniqueBeanDefinitionException.class, () -> ac.getBean(DiscountPolicy.class));
}
@Test
@DisplayName("부모 타입 조회 시, 자식이 둘 이상 있으면 빈 이름을 지정하자")
void findBeanByParentTypeBeanName(){
DiscountPolicy rateDiscountPolicy = ac.getBean("rateDiscountPolicy", DiscountPolicy.class);
assertThat(rateDiscountPolicy).isInstanceOf(RateDiscountPolicy.class);
}
🍘 BeanFactory와 ApplicationContext
BeanFactory
스프링 컨테이너의 최상위 인터페이스
스프링 빈을 관리하고 조회하는 역할 담당
getBean() 제공
ApplicationContext
BeanFactory 기능 모두 상속받아 제공
빈 관리 기능 + 여러 부가 기능
부가 기능 예시)
- 메시지소스 활용한 국제화 기능
- 환경변수 (로컬, 개발, 운영 등 구분하여 처리)
- 애플리케이션 이벤트 (이벤트를 발행, 구독하는 모델을 편리하게 지원)
- 편리한 리소스 조회 (파일, 클래스패스, 외부 등에서 리소스를 편리하게 조회)
🍘다양한 설정 형식 지원 - 자바 코드, XML ..
스프링 컨테이너는 다양한 형식의 설정 정보를 받아들일 수 있게 유연하게 설계되어 있음
ex) 자바 코드, XML, Groovy 등등
자바 코드(애노태이션 기반) => AnnotationConfigApplicationContext 클래스
XML => GenericXmlApplicationContext 클래스
🍘스프링 빈 설정 메타 정보 - BeanDefinition
BeanDefinition 추상화 => 스프링의 다양한 설정 형식 지원
역할과 구현을 개념적으로 나눈 것
스프링 컨테이너는 자바 코드인지, XML인지 몰라도 됨, BeanDefinition만 알면 됨
BeanDefinition을 빈 설정 메타정보라고 추상화함
각각 @Bean, 당 하나씩 메타 정보 생성
출처 : 김영한 스프링 핵심 원리