์ค์ ํ์ผ์ ์ด์ฉํด์ ์ง์  Bean์ ๋ฑ๋กํ๋ ๊ฒฝ์ฐ๊ฐ ์๋ ์ปดํฌ๋ํธ ์ค์บ์ ์ด์ฉํด์ ์คํ๋ง ์ปจํ ์ด๋์ Bean์ ๋ฑ๋กํ๋ ๊ฒฝ์ฐ ๋ฑ๋ก๋๋ Bean์ ๋ํด ์กฐ์ํ ์๊ฐ ์๋ค. (์ปดํฌ๋ํธ ์ค์บ์ ์ํด ์๋์ผ๋ก ๋ฑ๋ก๋๊ธฐ ๋๋ฌธ)
์ปดํฌ๋ํธ ์ค์บ์ ํตํด ๋ฑ๋ก๋๋ Bean์ ๋์ ํด์ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ๋ฑ๋กํ๊ณ ์ถ์ ๊ฒฝ์ฐ ๋ถ๊ฐ๋ฅํ ๊ฒ์ด๋ค.
๋น ํ์ฒ๋ฆฌ๊ธฐ๋ ์คํ๋ง ์ปจํ
์ด๋์ ๋ฑ๋ก๋๋ ๋ชจ๋  ๋น์ ๋ํด ์กฐ์์ด ๊ฐ๋ฅํ๋๋ก ๋์์ค๋ค.
๋ฑ๋ก๋๋ Bean์ ๋ํด์ ์ถ๊ฐ์ ์ธ ์์
๋ ๊ฐ๋ฅํ๊ณ  ๋์ผํ Bean์ด๋ฆ์ผ๋ก ์์ ๋ค๋ฅธ Bean์ ๋ฑ๋กํ๋ ๊ฒ๋ ๊ฐ๋ฅํ๋ค.
์์  ์๋๋ฆฌ์ค
๋ ๊ฐ ํด๋์ค ์์ฑ
    @Slf4j
    static class A {
        public void call() {
            log.info("Test A");
        }
    }
    @Slf4j
    static class B {
        public void call() {
            log.info("Test B");
        }
    }
Aํด๋์ค์ ๊ฐ์ฒด๋ง Bean์ผ๋ก ๋ฑ๋ก
    @Configuration
    static class BeanPostProcessorTestConfig {
        @Bean // A๋ง ๋น์ผ๋ก ๋ฑ๋ก
        public A a() {
            return new A();
        }
    }
๋นํ์ฒ๋ฆฌ๊ธฐ ๊ตฌํ
๋นํ์ฒ๋ฆฌ๊ธฐ๋ BeanPostProcessor ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๊ณ  ๊ตฌํํ ์ธํฐํ์ด์ค๋ฅผ Bean์ผ๋ก ๋ฑ๋กํ๋ ๊ฒ์ผ๋ก ๋์ํ๋ค.
@Slf4j
static class AToBPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        log.info("bean={}, beanName={}", bean, beanName);
        // ๋ฑ๋ก๋๋ ๋น์ด A ํ์
์ด๋ผ๋ฉด B์ ๊ฐ์ฒด๋ฅผ ์์ฑํด์ ๋ฑ๋กํ๋๋ก ์ฒ๋ฆฌ (Hooking)
        // ๋ฑ๋ก๋๋ ๋น์ ์ด๋ฆ์ ๊ทธ๋๋ก 'a' ์ด์ง๋ง ๋น์ ์ค์  ๊ฐ์ฒด๋ B ํ์
์ด ๋๋ค.
        if (bean instanceof A) return new B();
        return bean;
    }
}
๊ตฌํ๋ ๋นํ์ฒ๋ฆฌ๊ธฐ๋ฅผ Bean์ผ๋ก ๋ฑ๋กํ๋ค.
    @Configuration
    static class BeanPostProcessorTestConfig {
        @Bean // A๋ง ๋น์ผ๋ก ๋ฑ๋ก
        public A a() {
            return new A();
        }
        @Bean // ๋นํ์ฒ๋ฆฌ๊ธฐ ๋ฑ๋ก
        public AToBPostProcessor postProcessor() {
            return new AToBPostProcessor();
        }
    }
ํ ์คํธ
a๋ก ๋ฑ๋ก๋ Bean์ Bํด๋์ค ํ์
์ผ๋ก ์กฐํ๊ฐ ๊ฐ๋ฅํด์ผ ํ๋ค.@Test
void basicConfig() {
    ApplicationContext context = new AnnotationConfigApplicationContext(BeanPostProcessorTestConfig.class);
    B b = context.getBean("a", B.class);
    b.call();
    Assertions.assertThrows(NoSuchBeanDefinitionException.class, () -> context.getBean(A.class));
}

๋น ํ์ฒ๋ฆฌ๊ธฐ๋ฅผ ์ด์ฉํด์ ์ปดํฌ๋ํธ ์ค์บ์ ์ํด ์๋์ผ๋ก ๋ฑ๋ก๋๋ Bean์ ๋ํด์๋ ์กฐ์์ด ๊ฐ๋ฅํ๊ฒ ๋๋ค. ์ด ๊ธฐ๋ฅ์ ์ด์ฉํด์ ์ปดํฌ๋ํธ ์ค์บ์ผ๋ก ๋ฑ๋ก๋๋ Bean์ ๋ํด์๋ ํ๋ก์ ๊ฐ์ฒด๊ฐ ๋์ ํด์ ๋ฑ๋ก๋๋๋ก ํ๋ ๊ฒ์ด ๊ฐ๋ฅํ๋ค.
์ธํ๋ฐ - ์คํ๋ง ํต์ฌ ์๋ฆฌ ๊ณ ๊ธํธ (๊น์ํ ๋)