BeanFactoryPostProcessor 와 BeanPostProcessor에 대해서 알아보자
BeanFactoryPostProcessor 인터페이스는 한개의 메서드를 제공한다.
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
스프링 설정의 메타정보를 만들고 난뒤에 호출된다. 해당하는 어떤빈의 메타작업을 추가하고자 할때 쓰면 되는듯한데.. 그때가 언젠지는..
예제를 한번 살펴보자. 예제라기 보다는 그냥 한번 보자.
@Configuration
public class BeanFactoryPostProcessorTest implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] beanNames = beanFactory.getBeanDefinitionNames();
for(String beanName: beanNames){
System.out.println(beanName);
}
}
}
사용법은 아주 간단하다. BeanFactoryPostProcessor 를 구현한 클래스도 빈으로 등록이 되어 있어야 한다.
어떤 특정한 빈을 꺼내서 메타 정보를 수정 및 추가를 할 수는 있다. 스프링에는 BeanFactoryPostProcessor 구현한 클래스들이 많으니 그거를 참고하면 좋을듯 하다. 흑흑 나도 잘 모르겠다. 참고로 이 메서드는 클래스의 인스턴스화 되기전에 호출된다. 한마디로 정말 메타정보만 들고 있는 듯하다.
다음으론 BeanPostProcessor에 대해서 알아보자. BeanPostProcessor는 두개의 메서드를 제공해 주고 있다.
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
한개는 Initialization 전 또 다른 한개는 Initialization 후에 빈들을 조작할 수 있다. 여기서는 메타 정보를 조작하기보다는 빈객체들을 조작하는 듯 하다. 한번 예제를 살펴보자.
@Configuration
public class BeanPostProcessorTest implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if("initBean".equals(beanName)){
InitBean initBean = (InitBean) bean;
initBean.setName("wonwoo");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
InitBean 빈이라고 더미 객체를 한개 만들어서 테스트를 진행 했다. 아래와 같이 initBean이라는 빈이 있다고 가정하자.
@Component
public class InitBean implements InitializingBean {
private String name;
@Override
public void afterPropertiesSet() throws Exception {
System.out.println(name);
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
그리고 테스트를 해보면 최초에는 postProcessBeforeInitialization 메서드를 호출하고 난뒤에 InitializingBean인터페이스의 메서드인 afterPropertiesSet() 메서드를 호출하게 된다. 아까말했듯이 빈이 만들어 지기 전에 빈의 전처리를 할 수 있다.
InitBean클래스의 name을 넣어두었으니 afterPropertiesSet 호출시 name에는 wonwoo가 찍혀서 출력 될 것이다.
그럼 만약 빈이 등록되고 난뒤 즉(postProcessAfterInitialization) 후 처리에 name을 넣으면 어떻게 될까?
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if("initBean".equals(beanName)){
InitBean initBean = (InitBean) bean;
initBean.setName("wonwoo");
}
return bean;
}
코드만 살짝 바꿔서 테스트를 진행 하였다. 후 처리이기 때문에 afterPropertiesSet 호출시에는 name이 null로 출력된다. 이로써 빈의생성 전처리/후처리를 담당하는 것을 확인하였다. 실질적으로 BeanPostProcessor는 모든 빈에 적용된다. 만약 10개의 빈이 있다면 10번 호출된다. 하지만 BeanFactoryPostProcessor는 딱 한번 호출된다.
언제 쓰면 좋을지는 그때 가봐야 알 듯 하다. 지금 당장은 어디에 쓸지는 잘 모르겠다...
이렇게 아주 조금 BeanFactoryPostProcessor와 BeanPostProcessor를 알아봤다.