일반적인 스프링 빈 등록

Untitled

@Bean 이나 컴포넌트 스캔(@ComponentScan)으로 스프링 빈을 등록하면, 스프링은 대상 객체를 생성하고 스프링 컨테이너 내부의 빈 저장소에 등록한다. 그리고 이후에는 스프링 컨테이너를 통해 등록한 스프링 빈을 조회해서 사용하면 된다.

빈 후처리기 - BeanPostProcessor

스프링이 빈 저장소에 등록할 목적으로 생성한 객체를 빈 저장소에 등록하기 직전에 조작하고 싶을 경우 사용

Untitled

동작 과정

  1. 생성 : 스프링 빈 대상이 되는 객체를 생성한다 (@Bean, 컴포넌트 스캔 모두 포함)
  2. 전달 : 생성된 객체를 빈 저장소에 등록하기 전 빈 후처리기에 전달한다
  3. 후처리 작업 : 빈 후처리기는 전달된 스프링 빈 객체를 조작하거나 다른 객체로 바꿔치기 할 수 있다 (*이때 proxyA는 A객체를 참조하고 있다)
  4. 등록 : 빈 후처리기는 빈을 반환한다. 전달된 빈은 스프링 빈 저장소에 등록된다. (변경 없이 그대로 반환하거나, 바꿔치기 하거나)

빈 후처리기 테스트

A 객체를 B객체로 바꿔서 빈 저장소에 등록해보도록 한다 (이때 빈 후처리기를 구현 후 @Bean으로 등록해야 한다)

public class BeanPostProcessorTest {

    @DisplayName("")
    @Test
    void beanPostProcessorTest() {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanPostProcessorConfig.class);

        // beanA 이름으로 B객체가 빈으로 등록된다
        B b = applicationContext.getBean("beanA", B.class);
        b.helloB();

        // A는 빈으로 등록되지 않는다
        Assertions.assertThatThrownBy(() -> applicationContext.getBean(A.class))
                .isInstanceOf(NoSuchBeanDefinitionException.class);
    }

    @Slf4j
    @Configuration
    static class BeanPostProcessorConfig {
        @Bean(name = "beanA")
        public A a() {
            return new A();
        }

        @Bean
        public AtoBPostProcessor atoBPostProcessor() {
            return new AtoBPostProcessor();
        }
    }

    @Slf4j
    static class A {
        public void helloA() {
            log.info("hello A");
        }
    }

    @Slf4j
    static class B {
        public void helloB() {
            log.info("hello B");
        }
    }

    @Slf4j
    static  class AtoBPostProcessor implements BeanPostProcessor {
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            log.info("beanName = {} , bean = {}", beanName, bean);
            if(bean instanceof A) {
                return new B();
            }

            return bean;
        }
    }
}

정리