Spring 源碼剖析 四、主要邏輯代碼賞析之BeanFactoryPostProcessor對BeanFactory的攔截處理

  在web開發中,我們經常會用到一些攔截器,比如Java Web中的filter,已經Spring MVC中的Interceptor,其能對一個請求進行前置與後置的處理。而在Spring中,可以使用BeanFactoryPostProcessor對BeanFactory進行攔截處理。

  今天就來分析一下BeanFactoryPostProcessor對BeanFactory進行攔截處理的源碼。

 其中 BeanFactoryPostProcessor 不是環繞攔截,而是 beanFactory 初始化完成之後的攔截。其接口源碼爲:

public interface BeanFactoryPostProcessor {

	/**
	 * Modify the application context's internal bean factory after its standard
	 * initialization. All bean definitions will have been loaded, but no beans
	 * will have been instantiated yet. This allows for overriding or adding
	 * properties even to eager-initializing beans.
	 * @param beanFactory the bean factory used by the application context
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

  postProcessBeanFactory(beanFactory) 註釋上寫到,此方法用來修改applicationContext內部已經創建好的beanFactory,此時所有的beanDefinition已經加載完成,但是還沒有任何bean被實際創建,此方法允許給未創建的bean修改或增加參數,比如修改其beanDefinition。

  下面就來看一下 BeanFactoryPostProcessor 是如何來實現的,首先看一下ClassPathXmlApplicationContext 的初始化源碼:

	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {


			// 初始化 BeanFactory
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			. . .
			
			try {
				. . . 
				// 此爲執行所有的 BeanFactoryPostProcessors
				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				. . 

				// 此爲根據beanDefinition生成bean
				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);
			}
			. . .
		}
	}

  可以看到,refresh()方法先生成了BeanFactory,生成BeanFactory過程中會使用BeanDefinitionReader來讀取所有的BeanDefinition,然後注入到BeanFactory中。

  注入完成後,則會調用 invokeBeanFactoryPostProcessors(beanFactory) 來生成所有的BeanFactoryPostProcessors進行處理。

 我們看一下 invokeBeanFactoryPostProcessors(beanFactory) 方法的源碼:

 	// 從 beanDefinition 中獲取到所有類型爲 BeanFactoryPostProcessor 的beanName列表
	String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

	for (String ppName : postProcessorNames) {

		. . .
		nonOrderedPostProcessorNames.add(ppName);
		. . .
	}

	List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();

	// 得到這些BeanFactoryPostProcessor  的 bean,其實就是直接創建。
	for (String postProcessorName : nonOrderedPostProcessorNames) {
		nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
	}

	// 執行其方法,傳入beanFactory
	invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

可以看到,我們先獲取到了所有 BeanFactoryPostProcessor 類型的beanName列表,然後根據beanName列表生成了bean列表,再遍歷bean列表對BeanFactory進行後置處理。

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章