1. 程式人生 > >【spring系列】之7:生命週期-BeanPostProcessor原理以及在spring底層中的運用

【spring系列】之7:生命週期-BeanPostProcessor原理以及在spring底層中的運用

本章節重點說一下我們自定義的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);
 }