궁금증을 가지게 된 이유
-
스프링 문서를 보면서 공부하다가 위와 같은 문구를 보게 되었다.
ApplicationContext
가BeanFactory
의 서브 타입의 인터페이스라는 것이다. -
그렇다면 무슨 차이가 있을까라는 생각을 하게 되었다.
BEAN FACOTRY
다행스럽게도 위와 같은 문서가 스프링 공식문서에서 제공되고 있었다. 차이점은 아래와 같다.
BeanFactory
API는Spring IoC
기능을 위한 기초적인 기반을 제공한다.- 이것의 구체적인 계약은, 주로 스프링의 다른 부분과 관련된 써드 파티 프레임워크와의 통합에 사용된다.
BeanFactory
및 관련 인터페이스 (예:BeanFactoryAware
,Initializing Bean
,DispisableBean
)는 다른 프레임워크 구성 요소의 중요한 통합지점이다.- 어노테이션이랑 리플렉션이 필요하지 않으므로, 컨테이너와 컴포넌트간에 매우 효율적인 상호작용을 할 수 있다.
- 응용 프로그램 수준 빈은 동일한 콜백 인터페이스를 사용할 수 있지만, 일반적으로 어노테이션을 또는 설정을 통한 선언적 종속성 주입을 선호한다.
BeanFactory
API 레벨과,DefaultListableBeanFactory
구현에서는 구성 형식이나 사용할 구성 요소 어노테이션에 대해서 가정을 하지 않는다.- 이러한 것은 확장 기능(예:
XmlBeanDefinitionReader
,AutowiredAnnotationBeanPostProcessor
)을 통해서 제공되며, 공유BeanDefinition
개체에서 핵심 메타데이터 표현으로 작성한다. - 이것이 바로 스프링 컨테이너를 유연하고 확장 가능하게 만드는 본질이다.
솔직히 이 부분은 아직 잘 모르겠다… 그래도 정리를 해둔 기억이 있으니 코딩을 하면서 관련된 API를 사용할 때 다시 한번 확인해봐야겠다.
빈 펙토리와 애플리케이션 컨텍스트
-
이 섹션에서는
BeanFactory
와ApplicationContext
컨테이너 수준 간의 차이와 부트스트래핑에 대한 의미에 대해서 설명한다. -
커스텀 부트스트랩핑을
GenericApplicationContext
,AnnotationConfigApplicationContext
를 이용하여 구현할 것이 아니라면 일반적으로는ApplicationContext
를 사용해야한다. -
모든 공통 목적을 위해서 스프링의 핵심 컨테이너에 대한 기본 진입 지점이다.
-
ApplicationContext
에는BeanFactory
의 모든 기능이 포함되므로,BeanFactory
에 대한 완전한 제어가 필요한 시나리오를 제외하고 일반적으로BeanFactory
보다는ApplicationContext
를 사용하는 것을 권장한다. -
ApplicationContext
(일반 애플리케이션 컨텍스트 구현 등) 내에서 몇 가지 종류의 빈이 컨벤션에(특히,post-processors
) 의해서 탐지되는 반면에 일반DefaultListableBeanFactory
는 특별한 빈들에게 대해서 관련이 없다. -
주석 처리 및
AOP
프록시와 같은 많은 확장 컨테이너 기능의 경우,BeanPostProcessor
확장 지점이 필수적이다. -
일반
DefaultListableBeanFactory
만 사용하는 경우에는 기본적으로 이러한 사후 프로세스가 탐지 및 활성화 되지 않는다. -
빈 구성에 아무런 문제가 없기 때문에 이러한 상황은 혼란스러울 수 있지만 오히려 이러한 시나리오에서 컨테이너를 추가 설정을 통해서 완전히 부트스트랩 해야한다.
BeanFactory
는Bean
을 인스턴스화 하거나 와이어링 하는 것 빼고는ApplicationContext
과 비교해서 많은 기능을 제공하지 않는 것을 확인할 수 있다.
따라서 BeanFactory
에서 사후 프로세서를 명시적으로 등록하려면, 다음의 예외 같이 프로그래밍 방식으로 addBeanPostProcessor
를 호출해야한다.
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
// populate the factory with bean definitions
// now register any needed BeanPostProcessor instances
factory.addBeanPostProcessor(new AutowiredAnnotationBeanPostProcessor());
factory.addBeanPostProcessor(new MyBeanPostProcessor());
// now start using the factory
처음에 생각했던 것 과는 달리 기능을 제공하지 않을 뿐, 코드 상으로 설정을 해주면 사용할 수는 있다.
-
그래도 이렇게 명시적으로 등록을 해주어야 하기 때문에, 다양한
ApplicationContext
변형이 일반DefualtListableBeanFactory
보다 선호 된다. -
특히 일반적인 엔터프라이즈 환경에서 확장 컨테이너 기능을 위해서
BeanFactoryPostProcessor
및BeanPostProcessor
인스턴스에 의존하는 경우 더욱 그렇다.
일단 내가 생각하기에 가장 와닿는건 빈의 생명주기 관리를 할 수 없고, BeanPostProcessor
를 자동으로 등록해주지 않는다는 것이다. 뭐 수동으로 등록해주면 되기는 하지만, 상당히 불편하다.