@Bean
이나 컴포넌트 스캔(@ComponentScan
)으로 스프링 빈을 등록하면, 스프링은 대상 객체를 생성하고 스프링 컨테이너 내부의 빈 저장소에 등록한다. 그리고 이후에는 스프링 컨테이너를 통해 등록한 스프링 빈을 조회해서 사용하면 된다.
스프링이 빈 저장소에 등록할 목적으로 생성한 객체를 빈 저장소에 등록하기 직전에 조작하고 싶을 경우 사용
동작 과정
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;
}
}
}
정리