【spring系列】之7:生命週期-BeanPostProcessor原理以及在spring底層中的運用
阿新 • • 發佈:2019-01-05
本章節重點說一下我們自定義的BeanPostProcessor的執行機制和呼叫棧。
事前準備:
1.自定義beanPostProcessor
2.註冊自定義的beanPostProcessor到容器中
1.自定義beanPostProcessor
@Component public class LifeCycleBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof Toyota) { System.err.println("postProcessBeforeInitialization....攔截指定bean"); } System.out.println("這句話證明所有容器中的bean都會被postProcessBeforeInitialization攔截.. beanName=" + beanName + "==>" + bean); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof Toyota) { System.err.println("postProcessAfterInitialization.....攔截指定bean"); } System.out.println("這句話證明所有容器中的bean都會被postProcessAfterInitialization攔截.. beanName=" + beanName + "==>" + bean); return bean; } }
2.註冊自定義的beanPostProcessor到容器中
@Configuration @ComponentScan("com.ddc.fw.spring.annotation.demo.BeanPostProcessor") // 掃描自定義BeanPostProcessor public class LifeCycleConfig { @Bean(initMethod = "init", destroyMethod = "detory") // @Scope("prototype") public Toyota toyota() { return new Toyota(); } }
執行我們的測試程式碼:
@Test
public void testCar() {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(LifeCycleConfig.class);
printBeans(context);
context.getBean("toyota");
context.close();
}
現在我們通過junit的方法看一下呼叫棧:
紅色框內,便是執行到自定義的BeanPostProcessor的執行呼叫棧。
我們一步一步跟進去檢視:
第一步:
第二步:
第三步:
第四步:
第五步:
第六步:
第七步:
第八步:
第九步:
第十步:
第十一步:
第十二步:
第十三步:
遍歷得到容器中所有的BeanPostProcessor;挨個執行beforeInitialization,
一但返回null,跳出for迴圈,不會執行後面的BeanPostProcessor.postProcessorsBeforeInitialization
BeanPostProcessor原理
populateBean(beanName, mbd, instanceWrapper);給bean進行屬性賦值
initializeBean
{
applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
invokeInitMethods(beanName, wrappedBean, mbd);執行自定義初始化
applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}