머리 뽀개지는 BeanPostProcessor
이전 글에서 모든 Bean Life Cycle 콜백들을 구현하여 모든 콜백들이 예상대로 동작하는지 확인해봤습니다. 모든 메소드들이 제대로 동작했지만 BeanPostProcessor만 이상하게 동작하지 않았습니다.
결론부터 말씀드리면 재미없기 때문에 일단 코드를 보겠습니다.
<bean id="test2" class="net.agilejava.jedi.spring.beanLifeCycle.BeanLifeCycleTestBean" init-method="customInit" />
이 전 글에서 테스트 할 때 사용한 클레스를 다른 빈으로 하나 더 등록하고 테스트를 돌렸습니다.
setBeanClassLoader() 실행합니다.
setBeanFactory() 실행합니다.
setResourceLoader() 실행합니다.
setApplicationEventPublisher() 실행합니다.
setMessageSource() 실행합니다.
setApplicationContext() 실행합니다.
afterPropertiesSet() 실행합니다.
customInit() 실행합니다.
setBeanName() 실행합니다.
setBeanClassLoader() 실행합니다.
setBeanFactory() 실행합니다.
setResourceLoader() 실행합니다.
setApplicationEventPublisher() 실행합니다.
setMessageSource() 실행합니다.
setApplicationContext() 실행합니다.
postProcessBeforeInitialization() 실행합니다.
afterPropertiesSet() 실행합니다.
customInit() 실행합니다.
postProcessAfterInitialization() 실행합니다.
자 이제 수수께기가 풀리기 시작합니다. 제가 녹색으로 칠한 부분이 test 빈에서 찍힌것이고 v하늘색은 test1 빈에서 찍힌것입니다.
즉 BeanPostProcessor의 콜백 메소드들은 자신 이후에 생성되는 빈들에 적용됩니다.
좀 더 확실하게 확인하기 위해서 이번엔 세 개로 테스트 해보겠습니다.
<bean id="test2" class="net.agilejava.jedi.spring.beanLifeCycle.BeanLifeCycleTestBean" init-method="customInit" />
<bean id="test3" class="net.agilejava.jedi.spring.beanLifeCycle.BeanLifeCycleTestBean" init-method="customInit" />
결과는 다음과 같습니다,
setBeanClassLoader() 실행합니다.
setBeanFactory() 실행합니다.
setResourceLoader() 실행합니다.
setApplicationEventPublisher() 실행합니다.
setMessageSource() 실행합니다.
setApplicationContext() 실행합니다.
afterPropertiesSet() 실행합니다.
customInit() 실행합니다.
setBeanName() 실행합니다.
setBeanClassLoader() 실행합니다.
setBeanFactory() 실행합니다.
setResourceLoader() 실행합니다.
setApplicationEventPublisher() 실행합니다.
setMessageSource() 실행합니다.
setApplicationContext() 실행합니다.
postProcessBeforeInitialization() 실행합니다.
afterPropertiesSet() 실행합니다.
customInit() 실행합니다.
postProcessAfterInitialization() 실행합니다.
setBeanName() 실행합니다.
setBeanClassLoader() 실행합니다.
setBeanFactory() 실행합니다.
setResourceLoader() 실행합니다.
setApplicationEventPublisher() 실행합니다.
setMessageSource() 실행합니다.
setApplicationContext() 실행합니다.
postProcessBeforeInitialization() 실행합니다.
postProcessBeforeInitialization() 실행합니다.
afterPropertiesSet() 실행합니다.
customInit() 실행합니다.
postProcessAfterInitialization() 실행합니다.
postProcessAfterInitialization() 실행합니다.
하지만 bean 생성은 보통 설정 파일에 등록되어 있는 순서이고 depends-on 속성을 사용한다 하더라고 위 처럼 여러개의 BeanPostProcessor의 실행 순서를 예측하기란 사실 불안합니다.
그래서...BeanPostProcessor가 implements하고 있는 Orderd 인터페이스를 사용하여 순서를 지정할 수 있습니다.
BeanFactoryPostProcessor와의 차이는 BeanPostProcessor는 Bean 객체에 조작을 하는 반명 BeanFactoyPostProcessor는 Bean을 만드는 설명서에 해당하는 설정파일을 조작한다는 것입니다.