BeanFactoryPostProcessor

appti·2024년 3월 12일
0

분석

목록 보기
7/23

정의

BeanFactoryPostProcessor는 ApplicationContext에 등록된 BeanDefinition에 추가적인 설정을 하거나, BeanDefinition을 추가하는 일종의 팩토리 훅입니다.

특이사항으로는 BeanDefinition을 변경할 수는 있지만, 빈 인스턴스는 절대 생성하거나 수정하지 않는다는 점입니다.

BeanFactoryPostProcessor가 빈 인스턴스를 생성하거나 수정하게 된다면 빈이 조기에 인스턴스화 될 수 있어 컨테이너를 위반할 수 있기 때문입니다.

이로 인해 빈의 생명 주기나 IoC 컨테이너의 관리에 문제가 생길 수 있습니다.

예를 들어 스프링 부트에서 등록되는 빈은 Scope로 대부분 싱글톤을 지정하는데, BeanFactoryPostProcessor가 빈 인스턴스를 생성하거나 수정하게 된다면 이미 빈이 등록되어 있어 문제가 발생할 수 있습니다.

Ordered, PriorityOrdered

다른 BeanFactoryPostProcessor에 의존적인 BeanFactoryPostProcessor가 있을 수 있습니다.

이런 BeanFactoryPostProcessor는 Ordered 혹은 PriorityOrdered를 구현해 동작 순서를 지정할 수 있습니다.

주의할 점으로는 @Order로는 순서를 지정할 수 없다는 것입니다.

PropertySourceOrderingBeanFactoryPostProcessor의 경우 Order를 구현해 가장 높은 우선순위를 지정하고 있음을 확인할 수 있습니다.

이런 식으로 순서를 지정해야 하는 BeanFactoryPostProcessor의 대표적인 예시는CacheManagerEntityManagerFactoryDependsOnPostProcessor와 EntityManagerBeanDefinitionRegistrarPostProcessor의 관계입니다.

CacheManager가 동작하기 위해 EntityManager의 BeanDefinition이 필요하기 때문입니다.

그래서 위와 같이 BeanFactoryPostProcessor 동작 전 항상 정렬을 한 뒤 실행하는 것을 확인할 수 있습니다.

동작 시점

BeanFactoryPostProcessor는 빈 인스턴스를 생성하기 전에 동작합니다.

AbstractApplicationContext.refresh() 기준으로는 BeanPostProcessor가 등록되기 전에 BeanFactoryPostProcessor가 동작하고 있음을 확인할 수 있습니다.

그 이유는 빈 인스턴스를 생성하기 전, BeanDefinition에 대한 설정을 모두 마치기 위함입니다.

refresh에서 사용하는 BeanFactoryPostProcessor

BeanFactory가 BeanDefinitionRegistry일 때 ApplicationContext refresh에서 사용하는 BeanFactoryPostProcessor는 다음과 같습니다.

애노테이션 기반의 스프링 부트 3.0.8 버전, JPA에 의존하고 있는 환경입니다.

  • SpringApplication$PropertySourceOrderingBeanFactoryPostProcessor
    • 애플리케이션의 PropertySource를 정렬합니다.
    • 환경 변수, application.properties(yml) 등등에 등록한 모든 설정의 우선 순위를 고려해 정렬합니다.
  • SharedMetadataReaderFactoryContextInitializer$CachingMetadataReaderFactoryPostProcessor
    • 스프링 메타데이터 조회(Read) 성능을 최적화하기 위한 캐싱을 관리합니다.
    • 해당 BeanFactoryPostProcessor를 통해 클래스 메타데이터 조회 시 성능을 끌어올릴 수 있습니다.
  • ConfigurationWarningsApplicationContextInitializer$ConfigurationWarningsPostProcessor
    • ApplicationContext 시 Configuration에 대한 경고(Warning) 해주는 기능을 제공합니다.
    • 주로 권장하지 않는 Configuration 방식을 사용했거나, 빈 등록 시 문제가 발생할 수 있는 경우(순환 참조 등)을 경고해줍니다.
  • ConfigurationClassPostProcessor
    • @Configuration이 붙은 클래스에 대한 BeanDefinition을 조회합니다.
    • @Configuration, @ComponentScan 등 애노테이션 기반으로 등록된 빈의 BeanDefinition을 조회합니다.

  • PropertySourcesPlaceholderConfigurer
    • ${value}와 같은 Placeholder를 애플리케이션의 환경 설정 값으로 치환하는 기능을 제공합니다.
  • EntityManagerBeanDefinitionRegistrarPostProcessor
    • EntityManager의 BeanDefinition을 등록합니다.
  • CacheAutoConfiguration$CacheManagerEntityManagerFactoryDependsOnPostProcessor
    • 스프링 부트의 CacheAutoConfiguration 일부입니다.
    • 캐시와 EntityManager 간의 의존 관계를 처리합니다.
    • 캐시 설정보다 EntityManager의 BeanDefinition이 먼저 등록하도록 Ordered의 우선 순위를 지정합니다.
  • DatabaselnitializationDependencyConfigurer$DependsOnDatabaselnitializationPostProcessor
    • DB 초기화 이후 이와 관련된 빈들의 의존 관계를 설정하는 기능을 제공합니다.
  • EventListenerMethodProcessor
    • @EventListener가 명시된 메서드를 별도의 ApplicationListener로 변환해 BeanDefinition을 등록합니다.
  • AuditingBeanFactoryPostProcessor
    • @EnableJpaAuditing이 활성화 되었을 때 동작합니다.
    • 엔티티 생성 & 수정 시 자동으로 관련된 값들이 세팅되기 위한 LocalEntityManagerFactoryBean 혹은 LocalContainerEntityManagerFactoryBean의 BeanDefinition을 등록합니다.
  • ErrorMvcAutoConfiguration$PreserveErrorControllerTargetClassPostProcessor
    • ErrorController가 프록시 객체로 생성되었을 때, 원본 클래스 타입 정보를 유지할 수 있는 기능을 제공합니다.
profile
안녕하세요

0개의 댓글