728x90
public class BasicTest {
@Test
public void basicConfig() {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BasicConfig.class);
//A는 빈으로 등록된다.
A a = applicationContext.getBean("beanA", A.class);
a.helloA();
//B는 빈으로 등록되지 않는다.
Assertions.assertThrows(NoSuchBeanDefinitionException.class,
() -> applicationContext.getBean(B.class));
}
@Slf4j
@Configuration
static class BasicConfig {
@Bean(name = "beanA")
public A a() {
return new A();
}
}
@Slf4j
static class A {
public void helloA() {
log.info("hello A");
}
}
@Slf4j
static class B {
public void helloB() {
log.info("hello B");
}
}
}
- new AnnotationConfigApplicationContext(BasicConfig.class)
- 스프링 컨테이너를 생성하면서 BasicConfig.class를 넘겨주었다. BasicConfig.class 설정 파일은 스프링 빈으로 등록된다.
- BasicConfig.class
- beanA라는 이름으로 A 객체를 스프링 빈으로 등록하였다.
- A타입으로는 객체를 찾을수 있지만 B 타입으로는 객체를 찾을 수 없다.

- 빈 후처리기를 사용하려면 BeanPostProcessor 인터페이스를 구현하고, 스프링 빈으로 등록하면 된다.
- postProcessBeforeInitialization : 객체 생성 이후에 @PostConstruct 같은 초기화가 발생하기 전에 호출되는 포스트 프로세서이다.
- postProcessAfterInitialization : 객체 생성 이후에 @PostConstruct 같은 초기화가 발생한 다음에 호출되는 포스트 프로세서이다.
public class BeanPostProcessorTest {
@Test
public void basicConfig() {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(
BeanPostProcessorConfig.class);
//beanA 이름으로 B객체가 빈으로 등록된다.
B b = applicationContext.getBean("beanA", B.class);
b.helloB();
//B는 빈으로 등록되지 않는다.
Assertions.assertThrows(NoSuchBeanDefinitionException.class,
() -> applicationContext.getBean(A.class));
}
@Slf4j
@Configuration
static class BeanPostProcessorConfig {
@Bean(name = "beanA")
public A a() {
return new A();
}
@Bean
public AToBPostProcessor helloPostProcessor(){
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={}", bean, beanName);
if (bean instanceof A){
return new B();
}
return bean;
}
}
}
- AToBPostProcessor
- 빈 후처리기이다. 인터페이스인 BeanPostProcessor를 구현하고, 스프링 빈으로 등록하면 스프링 컨테이너가 빈 후처리기로 인식하고 동작한다.
- 이 빈 후처리기는 A 객체를 새로운 B 객체로 바꿔치기한다. 파라미터로 넘어오는 빈( bean ) 객체가 A의 인스턴스이면 새로운 B 객체를 생성해서 반환한다. 여기서 A 대신에 반환된 값인 B 가 스프링 컨테이너에 등록된다. 다음 실행결과를 보면 beanName=beanA , bean=A 객체의 인스턴스가 빈 후처리기에 넘어온 것을 확인할 수 있다
정리
빈 후처리기는 빈을 조작하고 변경할 수 있는 후킹 포인트이다. 이것은 빈 객체를 조작하거나 심지어 다른 객체로 바꾸어 버릴 수 있을 정도로 막강하다. 여기서 조작이라는 것은 해당 객체의 특정 메서드를 호출하는 것을 뜻한다. 일반적으로 스프링 컨테이너가 등록하는, 특히 컴포넌트 스캔의 대상이 되는 빈들은 중간에 조작할 방법이 없는데, 빈 후처리 기를 사용하면 개발자가 등록하는 모든 빈을 중간에 조작할 수 있다. 이 말은 빈 객체를 프록시로 교체하는 것도 가능하다는 뜻이다.
728x90
'스프링 핵심 원리(고급편)' 카테고리의 다른 글
| Ch07. 빈 후처리기 - 스프링이 제공하는 빈 후처리기 (0) | 2022.04.13 |
|---|---|
| Ch07. 빈 후처리기 - 빈 후처리기(적용) (0) | 2022.04.13 |
| Ch07. 빈 후처리기 - 빈 후처리기 (0) | 2022.04.13 |
| Ch06. 스프링이 지원하는 프록시 - 프록시 팩토리(적용) (0) | 2022.04.12 |
| Ch06. 스프링이 지원하는 프록시 - 어드바이저(예제) (0) | 2022.04.12 |