BeanPostProcessor와 BeanFactoryPostProcessor의 차이는 뭘까?
코드를 살펴보았을 때, 둘 다 인터페이스라는 것은 동일하다. 큼직하게 본다면 함수형 인터페이스냐 아니냐의 차이라고 볼 수 있을 것 같다.
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
@FunctionalInterface
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;
}
다음으로는 메서드명을 통해 생각해보자.
BeanPostProcessor에는 postProcessBeforeInitialization(), postProcessAfterInitialization()
이 있다. 의미만 해석해본다면, 초기화 전에 전처리(), 초기화 후의 전처리()
다. 이 두 개의 메서드는 빈 생성 시에 대한 처리라는 것을 유추할 수 있다.
반대로 BeanFactoryPostProcessor에는 postProcessBeanFactoy()
메서드 하나만 있다. 이것도 의미만 해석해보면 BeanFactory전에 처리()
를 의미한다. 그럼 여기서 BeanFactory를 생각해보자. BeanFactory는 빈을 생성해주고 의존 관계를 설정해주는 클래스다.
여기까지 내가 해석한 것이 맞다면, 코드로만 살펴보았을 때 BeanFactoryPostProcessor는 빈 인스턴스화 전에 실행이 되는 것이고, BeanPostProcessor는 빈 객체의 라이프 사이클(초기화 전, 후)에서 실행되는 것임을 생각할 수 있다.
BeanPostProcess와 BeanFactoryPostProcess의 차이점에 대해 검색하다가 발견한 StackOverflow에서는 내가 코드로 살펴보았던 것과 동일한 답변이 달려있었다. (내가 옳았다! 😆)
이미지를 보면, BeanFactoryPP 시점에 BeanFactoryPostProcessor, BeanPP의 시점에는 BeanPostProcessor라는 표현을 볼 수 있고, 이 두 시점 사이에는 빈의 생성과 의존성 주입에 대한 처리가 이루어지는 것을 볼 수 있다.
추가적으로 BeanFactory 공식 문서에서도 초기화 전과 후를 BeanPostProcessor로 감싸여진 내용이 언급되어있다.
11. postProcessBeforeInitialization methods of BeanPostProcessors
12. InitializingBean's afterPropertiesSet
13. a custom init-method definition
14. postProcessAfterInitialization methods of BeanPostProcessors
여기서 헷갈릴 수는 있으나 결국에는 BeanFactoryPostProcessor는 빈에 대한 조작을 하기도 시작하기 전에 처리하는 것이고, BeanPostProcessor는 빈이 생성되는 시점 - 빈이 초기화되는 시점(전,후)에서 처리를 하는 것이다.
💡 BeanPostProcessord의 구현체 AutowiredAnnotationBeanPostProcessor?
AutowiredAnnotationBeanPostProcessor는 하나의 빈으로 IoC 컨테이너에 등록되어있는 BeanPostProcessor의 구현체다. 이 구현체는 빈이 생성되기 전에
@Autowired
어노테이션이 붙어있으면 해당하는 빈을 찾아서 주입해주는 작업을 처리해준다.
더 찾아봐야하지만, @EnableAsync
도 BeanPostProcessor를 이용하는 것 같으니 해당 내용에 대해서는 꼭 숙지할 필요가 있어보인다.