ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • BeanFactoryPostProcessor 와 BeanPostProcessor
    카테고리 없음 2023. 4. 20. 09:53
    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를 알아봤다.

    댓글

Designed by Tistory.