궁금증을 가지게 된 이유


Screen Shot 2021-03-24 at 11 38 22 PM

  • 스프링 문서를 보면서 공부하다가 위와 같은 문구를 보게 되었다. ApplicationContextBeanFactory의 서브 타입의 인터페이스라는 것이다.

  • 그렇다면 무슨 차이가 있을까라는 생각을 하게 되었다.

BEAN FACOTRY


Screen Shot 2021-03-24 at 11 41 55 PM

다행스럽게도 위와 같은 문서가 스프링 공식문서에서 제공되고 있었다. 차이점은 아래와 같다.

  • BeanFactory API는 Spring IoC 기능을 위한 기초적인 기반을 제공한다.
  • 이것의 구체적인 계약은, 주로 스프링의 다른 부분과 관련된 써드 파티 프레임워크와의 통합에 사용된다.
  • BeanFactory 및 관련 인터페이스 (예: BeanFactoryAware, Initializing Bean, DispisableBean)는 다른 프레임워크 구성 요소의 중요한 통합지점이다.
  • 어노테이션이랑 리플렉션이 필요하지 않으므로, 컨테이너와 컴포넌트간에 매우 효율적인 상호작용을 할 수 있다.
  • 응용 프로그램 수준 빈은 동일한 콜백 인터페이스를 사용할 수 있지만, 일반적으로 어노테이션을 또는 설정을 통한 선언적 종속성 주입을 선호한다.
  • BeanFactory API 레벨과, DefaultListableBeanFactory 구현에서는 구성 형식이나 사용할 구성 요소 어노테이션에 대해서 가정을 하지 않는다.
  • 이러한 것은 확장 기능(예: XmlBeanDefinitionReader, AutowiredAnnotationBeanPostProcessor)을 통해서 제공되며, 공유 BeanDefinition 개체에서 핵심 메타데이터 표현으로 작성한다.
  • 이것이 바로 스프링 컨테이너를 유연하고 확장 가능하게 만드는 본질이다.

솔직히 이 부분은 아직 잘 모르겠다… 그래도 정리를 해둔 기억이 있으니 코딩을 하면서 관련된 API를 사용할 때 다시 한번 확인해봐야겠다.

빈 펙토리와 애플리케이션 컨텍스트


Screen Shot 2021-03-25 at 12 02 28 AM

  • 이 섹션에서는 BeanFactoryApplicationContext 컨테이너 수준 간의 차이와 부트스트래핑에 대한 의미에 대해서 설명한다.

  • 커스텀 부트스트랩핑을 GenericApplicationContext, AnnotationConfigApplicationContext를 이용하여 구현할 것이 아니라면 일반적으로는 ApplicationContext를 사용해야한다.

  • 모든 공통 목적을 위해서 스프링의 핵심 컨테이너에 대한 기본 진입 지점이다.

  • ApplicationContext에는 BeanFactory의 모든 기능이 포함되므로, BeanFactory에 대한 완전한 제어가 필요한 시나리오를 제외하고 일반적으로 BeanFactory보다는 ApplicationContext를 사용하는 것을 권장한다.

  • ApplicationContext(일반 애플리케이션 컨텍스트 구현 등) 내에서 몇 가지 종류의 빈이 컨벤션에(특히, post-processors) 의해서 탐지되는 반면에 일반 DefaultListableBeanFactory는 특별한 빈들에게 대해서 관련이 없다.

  • 주석 처리 및 AOP 프록시와 같은 많은 확장 컨테이너 기능의 경우, BeanPostProcessor 확장 지점이 필수적이다.

  • 일반 DefaultListableBeanFactory만 사용하는 경우에는 기본적으로 이러한 사후 프로세스가 탐지 및 활성화 되지 않는다.

  • 빈 구성에 아무런 문제가 없기 때문에 이러한 상황은 혼란스러울 수 있지만 오히려 이러한 시나리오에서 컨테이너를 추가 설정을 통해서 완전히 부트스트랩 해야한다.

Screen Shot 2021-03-25 at 12 02 42 AM

  • BeanFactoryBean을 인스턴스화 하거나 와이어링 하는 것 빼고는 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 보다 선호 된다.

  • 특히 일반적인 엔터프라이즈 환경에서 확장 컨테이너 기능을 위해서 BeanFactoryPostProcessorBeanPostProcessor 인스턴스에 의존하는 경우 더욱 그렇다.

일단 내가 생각하기에 가장 와닿는건 빈의 생명주기 관리를 할 수 없고, BeanPostProcessor를 자동으로 등록해주지 않는다는 것이다. 뭐 수동으로 등록해주면 되기는 하지만, 상당히 불편하다.

참고 문헌

>> Home