9-Spring容器創建之refresh(3)——【prepareBeanFactory】與【postProcessBeanFactory】

上一篇:8-Spring容器創建之refresh(2)——【prepareRefresh】與【ConfigurableListableBeanFactory】

上一篇文章介紹了refresh方法中的前兩個方法,本篇文章我們繼續介紹refresh方法中的第三個方法prepareBeanFactory和第四個方法postProcessBeanFactory

1. prepareBeanFactory

這個方法設置beanFactory的標準上下文特徵,爲beanFactory設置類加載器、後置處理器等。其中主要注意一下這裏面增加了2個beanFactory的後置處理器,由於BeanbeanFactory在Spring中都有後置處理器,所以要優先注意一下。這裏需要強調一點:beanFactory在想要擁有後置處理器時,必須通過顯示的調用addBeanPostProcessor才能獲得。

	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// 設置beanFactory的類加載器classLoader爲當前context的類加載器.
		beanFactory.setBeanClassLoader(getClassLoader());
		// 設置SpEL表達式解析器(在Bean初始化完成之後填充屬性的時候用到)
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		// 添加屬性編輯註冊器(註冊屬性編輯器),屬性編輯器實際上是屬性的類型轉換器
		// 因爲bean的屬性配置都是字符串類型的 實例化的時候要將這些屬性轉換爲實際類型
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// 添加beanFactory的後置處理器
		// 在Bean初始化之前,調用ApplicationContextAwareProcessor的postProcessBeforeInitialization
    	// 處理所有的Aware接口,進行如下操作:
    	// 1. 如果bean實現了EnvironmentAware接口,調用bean.setEnvironment
    	// 2. 如果bean實現了EmbeddedValueResolverAware接口,調用bean.setEmbeddedValueResolver
    	// 3. 如果bean實現了ResourceLoaderAware接口,調用bean.setResourceLoader
    	// 4. 如果bean實現了ApplicationEventPublisherAware接口,調用bean.setApplicationEventPublisher
    	// 5. 如果bean實現了MessageSourceAware接口,調用bean.setMessageSource
    	// 6. 如果bean實現了ApplicationContextAware接口,調用bean.setApplicationContext
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		
		// 忽略自動裝配,在注入的時候忽略此方法指定的接口類。也就是指定的接口不會被注入進去
		// 可以忽略的原因是:ApplicationContextAwareProcessor把這五個接口的實現工作做完了
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

		// BeanFactory interface not registered as resolvable type in a plain factory.
		// MessageSource registered (and found for autowiring) as a bean.
		// 下面這4個class 會被加入到beanFactory的resolvableDependencies字段裏面緩存這,
		// 爲後面處理依賴注入的時候使用 DefaultListableBeanFactory#resolveDependency處理依賴關係
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// Register early post-processor for detecting inner beans as ApplicationListeners.
		// // 添加beanFactory的後置處理器   事件監聽器
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// Register default environment beans.
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
	}

這裏面需要注意兩個地方,第一個地方就是增加了beanFactoryBeanPostProcessor,在上述代碼執行完成後,我們的beanFactory中的beanPostProcessor裏會增加兩個:
在這裏插入圖片描述

第二個地方就是增加了處理依賴關係的4個類:

在這裏插入圖片描述

2. postProcessBeanFactory方法

該方法是一個留給子類的空方法。子類通過重寫這個方法來在BeanFactory創建並預準備完成以後做進一步的設置

3. 總結

以上是refresh方法中調用的第三個方法prepareBeanFactory和第四個方法postProcessBeanFactory
一下篇文章我們來接着介紹refresh的第五個方法,也是非常重要的方法:invokeBeanFactoryPostProcessors(beanFactory);

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