BeanPostProcessor / BeanFactoryPostProcessor

2025. 3. 6. 20:59Spring Framework/Spring IoC

📌 BeanPostProcessor 및 BeanFactoryPostProcessor 완전 정리 🚀

DefaultListableBeanFactory는 스프링의 핵심 빈 팩토리 구현체로 확장성이 뛰어나며, BeanPostProcessorBeanFactoryPostProcessor를 통해 빈의 생성, 초기화, 및 라이프사이클을 조작할 수 있습니다.

📌 1️⃣ DefaultListableBeanFactory의 확장성 개요

스프링은 빈의 생성, 초기화, 의존성 주입, 소멸 등 다양한 단계에서 개입할 수 있는 확장 포인트를 제공합니다.
특히 BeanPostProcessorBeanFactoryPostProcessor는 스프링 컨테이너 내부에서 자동으로 실행되며,
빈이 생성되거나 컨테이너가 초기화될 때 추가적인 로직을 적용하는 강력한 확장 기법입니다.

BeanPostProcessor → 개별 빈(Bean)의 초기화 로직을 가로채서 후처리
BeanFactoryPostProcessor → 빈 팩토리(BeanFactory) 레벨에서 모든 빈 정의(BeanDefinition)를 수정 가능

📌 스프링 빈 생성 과정에서 개입하는 지점

1. 빈 정의(BeanDefinition) 등록
2. BeanFactoryPostProcessor 실행 (빈 인스턴스 생성 전, BeanDefinition을 수정 가능)
3. 빈 인스턴스 생성 (createBean)
4. BeanPostProcessor (전처리, @PostConstruct 실행 등)
5. 의존성 주입 (populateBean)
6. 빈 초기화 (afterPropertiesSet, init-method)
7. BeanPostProcessor (후처리)
8. 빈 사용
9. 빈 소멸 (destroy-method, @PreDestroy)

📌 2️⃣ BeanPostProcessor (빈 후처리기)

✅ BeanPostProcessor란?

BeanPostProcessor빈이 초기화될 때(@PostConstruct, afterPropertiesSet, init-method 실행 전후)에 추가 작업을 수행할 수 있도록 하는 인터페이스입니다.
✔ 모든 빈(Bean)에 대해 공통적인 초기화 후처리 로직을 적용할 수 있는 확장 포인트입니다.
AOP, 트랜잭션, @Autowired 주입 처리 등도 내부적으로 BeanPostProcessor를 사용합니다.

📌 BeanPostProcessor 인터페이스

public interface BeanPostProcessor {
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

postProcessBeforeInitialization() → 빈 초기화(@PostConstruct, afterPropertiesSet()) 실행 수행
postProcessAfterInitialization() → 빈 초기화 실행 수행

✅ BeanPostProcessor 구현 예제

📌 모든 빈에 대해 특정 로직을 실행하는 후처리기

import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        System.out.println("🚀 빈 초기화 전 (Before Init): " + beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        System.out.println("✅ 빈 초기화 후 (After Init): " + beanName);
        return bean;
    }
}

✔ 스프링 컨테이너가 빈을 생성할 때 모든 빈의 초기화 과정에서 개입 가능
postProcessBeforeInitialization()에서 초기화 전에 로직 추가 가능
postProcessAfterInitialization()에서 AOP 적용, 프록시 래핑 등 가능

📌 실행 결과

🚀 빈 초기화 전 (Before Init): myService
✅ 빈 초기화 후 (After Init): myService

✅ BeanPostProcessor 응용 사례

📌 특정 애노테이션(@MyCustom) 기반으로 동작하는 후처리기

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyCustom {
}
import org.springframework.stereotype.Component;

@MyCustom
@Component
public class CustomService {
    public void execute() {
        System.out.println("Executing CustomService...");
    }
}

📌 @MyCustom이 붙은 빈에 대해 추가 설정 적용

import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

@Component
public class CustomAnnotationProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        if (bean.getClass().isAnnotationPresent(MyCustom.class)) {
            System.out.println("🎯 @MyCustom이 적용된 빈: " + beanName);
        }
        return bean;
    }
}

@MyCustom이 붙은 빈이 생성될 때 추가 작업 수행
✔ 특정 빈을 감지하여 AOP, 로깅, 설정 변경 등의 추가 로직을 적용 가능

📌 3️⃣ BeanFactoryPostProcessor (빈 팩토리 후처리기)

✅ BeanFactoryPostProcessor란?

BeanFactoryPostProcessor빈이 인스턴스화되기 전
BeanDefinition을 직접 수정할 수 있는 확장 포인트
빈 팩토리 자체를 조작할 수 있어, 빈의 속성을 동적으로 변경 가능
✔ 대표적인 예: PropertyPlaceholderConfigurer, ConfigurationClassPostProcessor (Spring 내부에서 사용)

📌 BeanFactoryPostProcessor 인터페이스

public interface BeanFactoryPostProcessor {
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}

모든 빈이 등록된 후, 빈 생성 전에 실행
✔ 빈을 조작하는 것이 아니라 빈 정의(BeanDefinition)를 수정하는 역할

✅ BeanFactoryPostProcessor 구현 예제

📌 BeanDefinition을 동적으로 변경하는 후처리기

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;

@Component
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("🛠 BeanFactoryPostProcessor 실행 중...");

        // 특정 빈의 BeanDefinition 수정
        BeanDefinition beanDefinition = beanFactory.getBeanDefinition("myService");
        beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE); // 싱글톤 → 프로토타입 변경
    }
}

"myService" 빈을 싱글톤 → 프로토타입으로 변경
빈이 생성되기 전에 BeanDefinition을 수정 가능

✅ BeanFactoryPostProcessor와 BeanPostProcessor 차이점

기능 BeanPostProcessor BeanFactoryPostProcessor
실행 시점 빈 초기화 전후 빈 정의가 등록된 후, 빈 생성 전
적용 대상 개별 빈(Bean) 빈 정의(BeanDefinition)
주요 역할 빈의 로직 후처리 (AOP, 프록시 적용) 빈 정의 수정 (스코프 변경, 속성 변경)
실행 횟수 빈 개수만큼 실행 컨테이너 1회 실행

📌 4️⃣ Summary

DefaultListableBeanFactory는 확장성이 뛰어나 빈 생성 및 초기화 과정에서 개입 가능
BeanPostProcessor → 개별 빈(Bean)의 초기화 과정 후처리 (AOP, 프록시, 로깅 등 활용)
BeanFactoryPostProcessor → 빈 정의(BeanDefinition) 수정 가능 (스코프 변경, 속성 조작 등)
AOP, 트랜잭션, 설정 값 변경 등 다양한 기능을 구현할 때 필수적인 확장 포인트

 

🚀 스프링 컨테이너 내부를 깊이 이해하려면 BeanPostProcessorBeanFactoryPostProcessor 활용법을 숙지하는 것이 중요합니다!

 

 

'Spring Framework > Spring IoC' 카테고리의 다른 글

DefaultListableBeanFactory의 확장성이란?  (0) 2025.03.06
@Order  (0) 2025.01.26
엔터프라이즈 관련 기능  (1) 2025.01.16
Service Locator Pattern  (1) 2025.01.16
Spring IoC  (0) 2024.11.15