Section4(2편) BeanFactory와 ApplicationContext
인프런 강의 中
김영한 강사님의 '스프링 핵심 원리' 내용을 정리했습니다.

이전 시간에는 스프링 컨테이너에 빈이 등록되는 과정과 빈 조회 방법을 학습해 보았다. 이번시간에는 스프링 컨테이너를 생성하기 위해 사용했던 AnnotationConfigApplicationContext 클래스와 스프링 컨테이너의 최상위 인터페이스인 BeanFactory, 그리고 BeanFactory를 상속받고 있는 ApplicationContext에 대해서 김영한 강사님의 강의를 통해 학습해 보겠다.
AnnotationConfigApplicationContext 클래스의 상속 구조

우리가 컨테이너 생성을 위해 사용했던 AnnotationConfigApplicationContext 클래스는 위 그림과 같이 상속을 받고 있다.
각 인터페이스들과 클래스가 어떤 역할을 하는지 간략하게 살펴보자.
BeanFactory
- 스프링 컨테이너의 최상위 인터페이스다.
- 스프링 빈을 관리하고 조회하는 역할을 담당한다.
- getBean()을 제공한다. => 우리가 Bean 조회를 위해 사용했던 메소드가 BeanFactory 인터페이스에 있던 것이다.
- 지금까지 우리가 사용했던 대부분의 기능은 BeanFactory가 제공하는 기능이다.
ApplicationContext
- BeanFactory 기능을 모두 상속받아서 제공한다.
- 부가적으로 다음과 같은 인터페이스를 상속 받아서 다양한 부가 기능을 제공한다.

- 메시지 소스를 활용한 국제화 기능
- 예를 들어, 한국에서 들어오면 한국어로, 영어권에서 들어오면 영어로 출력
- 환경변수
- 로컬, 개발, 운영 등을 구분해서 처리
- 애플리케이션 이벤트
- 이벤트를 발행하고 구독하는 모델을 편리하게 지원
- 편리한 리소스 조회
- 파일, 클래스패스, 외부 등에서 리소스를 편리하게 조회
아직 위와 같은 부가 기능을 사용해보지 못해서 와닿지 않는다. 하지만 나중에 꼭 사용해보고 부가 기능들을 익혀볼 것이다.
다양한 설정 형식 지원 - 자바 코드, XML

우리가 AnnotationConfigApplicationContext를 사용해서 컨테이너를 생성했던 것처럼 다른 구현체 클래스를 사용해서 컨테이너를 생성하고 빈 등록을 할 수 있다. 하지만 여기서 주의해야 할 점이 있다. 바로 클래스가 지원하는 설정 파일을 파라미터로 넘겨야 한다는 것이다. GenericXmlApplicationContext 클래스는 위 구조도에 나와있는 것처럼 xml파일을 설정 파일로 사용해야 한다. xml을 사용하는 것은 옛날 방식이긴 하지만 알아두는 것이 좋다. xml을 사용하는 회사에서 코드 작성을 할 수 도 있기 때문이다.
xml 설정 사용
최근에는 스프링 부트를 많이 사용하면서 XML기반의 설정은 잘 사용하지 않는다. 아직 많은 레거시 프로젝트 들이 XML로 되어 있고, 또 XML을 사용하면 컴파일 없이 빈 설정 정보를 변경할 수 있는 장점도 있으므로 한 번쯤 배워두는 것도 좋다.
XML을 사용해서 컨테이서를 생성한 빈 등록 테스트 코드
@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
@Bean
public OrderService orderService() {
return new OrderServiceImpl(
memberRepository(),
discountPolicy());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
@Bean
public DiscountPolicy discountPolicy() {
return new RateDiscountPolicy();
}
}
기존의 java 파일로 설정했던 빈 등록 설정 파일 정보
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://
www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="memberService" class="hello.core.member.MemberServiceImpl">
<constructor-arg name="memberRepository" ref="memberRepository" />
</bean>
<bean id="memberRepository"
class="hello.core.member.MemoryMemberRepository" />
<bean id="orderService" class="hello.core.order.OrderServiceImpl">
<constructor-arg name="memberRepository" ref="memberRepository" />
<constructor-arg name="discountPolicy" ref="discountPolicy" />
</bean>
<bean id="discountPolicy" class="hello.core.discount.RateDiscountPolicy" />
</beans
xml 파일로 만든 빈 설정 파일 정보
xml 설정 파일을 보면 이전에 생성했던 AppConfig.java로 빈 생성을 했을 때와 확실히 코드 차이가 나는 것을 알 수 있다. 하지만 xml 설정 파일과 class 설정 파일을 동일한 내용이다.

테스트 코드에서는 GenericXmlApplicationContext 구현체를 사용한 것 외에는 크게 달라진 것은 없다.
이스프링 컨테이너의 최상위 인터페이스인 BeanFactory의 상속을 받아서 다양한 형식으로 컨테이너를 생성하고 빈을 관리 및 조회할 수 있었다. 다음 시간에는 다양한 형식으로 빈을 설정하는 역할의 핵심인 BeanDefinition에 대해 김영한 강사님의 강의를 통해 정리해보겠다.
!!김영한 강사님 강의