天天看點

Spring源碼分析:IOC容器初始化(一)前言refresh 源碼分析總結參考

原文釋出于: http://blog.ztgreat.cn/article/57

前言

在前面 先分析了最底層的IOC容器BeanFactory,接着簡單分析了進階形态的容器ApplicationContext,在ApplicationContext 中我們知道一個核心方法 refresh,這裡面就是IOC容器的初始化流程,在前面并沒有直接去分析它,隻是簡單的分析了BeanDefinition的載入,解析注冊,有了這些基礎後,再來完整的分析IOC容器的啟動流程,并在适當的時候通過例子來說明。

需要以下基礎内容:

Spring-BeanFactory源碼分析(一)

Spring-統一資源加載政策

Spring-BeanFactory源碼分析(二)

refresh 源碼分析

在 AbstractApplicationContext 中以及将refresh整個流程定義出來了,我們再來看refresh 源碼。

@Override
public void refresh() throws BeansException, IllegalStateException {
   // 同步操作
   synchronized (this.startupShutdownMonitor) {

      // 準備工作,記錄下容器的啟動時間、标記"已啟動"狀态
      prepareRefresh();

      // 這步在前面我們分析過,這步主要将配置檔案就會解析成一個個 Bean 定義,注冊到 BeanFactory 中,
      // 但是此時 Bean 還沒有初始化,隻是配置資訊都提取出來了,
      //這步中有 customizeBeanFactory 方法,具體在後面介紹
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // 設定 BeanFactory 的類加載器,添加幾個 BeanPostProcessor,手動注冊幾個特殊的 bean
      //這個後面會具體介紹
      prepareBeanFactory(beanFactory);

      try {
         // 如果 Bean 實作了BeanFactoryPostProcessor接口,
         // 那麼在容器初始化以後,Spring 會負責調用裡面的 postProcessBeanFactory 方法。

         // 這裡是提供給子類的擴充點,到這裡的時候,所有的 Bean 都加載、注冊完成了,但是都還沒有初始化
         // 具體的子類可以在這步的時候添加一些特殊的 BeanFactoryPostProcessor 的實作類或做點什麼事
         postProcessBeanFactory(beanFactory);
         // 調用 BeanFactoryPostProcessor 各個實作類的 postProcessBeanFactory(factory) 方法
         invokeBeanFactoryPostProcessors(beanFactory);

         // 注冊 BeanPostProcessor 的實作類,注意看和 BeanFactoryPostProcessor 的差別
         // 此接口兩個方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
         // 兩個方法分别在 Bean 初始化之前和初始化之後得到執行。注意,到這裡 Bean 還沒初始化
         registerBeanPostProcessors(beanFactory);

         // 初始化目前 ApplicationContext 的 MessageSource,不是重點,忽略
         initMessageSource();

         // 初始化目前 ApplicationContext 的事件廣播器,忽略
         initApplicationEventMulticaster();

         // 模闆方法
         // 具體的子類可以在這裡做一些特殊操作
         onRefresh();

         // 注冊事件監聽器,監聽器需要實作 ApplicationListener 接口,忽略
         registerListeners();

         // 初始化所有的 singleton beans
         //(lazy-init 的除外)
         finishBeanFactoryInitialization(beanFactory);

         // 最後,廣播事件,ApplicationContext 初始化完成
         finishRefresh();
      }

      catch (BeansException ex) {
         if (logger.isWarnEnabled()) {
            logger.warn("Exception encountered during context initialization - " +
                  "cancelling refresh attempt: " + ex);
         }

         // Destroy already created singletons to avoid dangling resources.
         // 銷毀已經初始化的 Bean
         destroyBeans();

         // Reset 'active' flag.
         cancelRefresh(ex);
         
         throw ex;
      }

      finally {
         // Reset common introspection caches in Spring's core, since we
         // might not ever need metadata for singleton beans anymore...
         resetCommonCaches();
      }
   }
}
           

準備工作-prepareRefresh

protected void prepareRefresh() {
   // 記錄啟動時間,
   this.startupDate = System.currentTimeMillis();
   // 設定容器狀态
   this.closed.set(false);
   this.active.set(true);

   if (logger.isInfoEnabled()) {
      logger.info("Refreshing " + this);
   }

   // Initialize any placeholder property sources in the context environment
   initPropertySources();

   // 校驗 xml 配置檔案
   getEnvironment().validateRequiredProperties();

   this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
}
           

這個比較簡單,問題不大。

建立 Bean 容器,加載,注冊 Bean

我們回到 refresh() 方法中的下一行 obtainFreshBeanFactory()。

注意,這個方法很重要,這裡将會初始化 BeanFactory、加載 Bean、注冊 Bean 等等。

在Spring-BeanFactory源碼分析(二) 中我們大緻分析過了這個方法,這裡就簡單提一下就可以了,看一下在前面文章中沒有提及的方法。

AbstractApplicationContext

->

obtainFreshBeanFactory

:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
   // 關閉舊的 BeanFactory (如果有),建立新的 BeanFactory,加載 Bean 定義、注冊 Bean 等等
   refreshBeanFactory();

   ConfigurableListableBeanFactory beanFactory = getBeanFactory();
   if (logger.isDebugEnabled()) {
      logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
   }
   return beanFactory;
}
           

AbstractRefreshableApplicationContext

->

refreshBeanFactory

:

@Override
protected final void refreshBeanFactory() throws BeansException {
  
   if (hasBeanFactory()) {
      destroyBeans();
      closeBeanFactory();
   }
   try {
      // 初始化一個 DefaultListableBeanFactory
      DefaultListableBeanFactory beanFactory = createBeanFactory();
      // 用于 BeanFactory 的序列化
      beanFactory.setSerializationId(getId());

      // 設定 BeanFactory 的兩個配置屬性:是否允許 Bean 覆寫、是否允許循環引用
      customizeBeanFactory(beanFactory);

      // 加載 Bean 到 BeanFactory 中
      loadBeanDefinitions(beanFactory);
      synchronized (this.beanFactoryMonitor) {
         this.beanFactory = beanFactory;
      }
   }
   catch (IOException ex) {
      throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
   }
}
           

這裡主要看一下 customizeBeanFactory 方法:

protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
  if (this.allowBeanDefinitionOverriding != null) {
    // 是否允許 Bean 定義覆寫
  	beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
  }
  if (this.allowCircularReferences != null) {
    // 是否允許 Bean 間的循環依賴
  	beanFactory.setAllowCircularReferences(this.allowCircularReferences);
  }
}
           

BeanDefinition 的覆寫問題就是在配置檔案中定義 bean 時使用了相同的 id 或 name,預設情況下,allowBeanDefinitionOverriding 屬性為 null,如果在同一配置檔案中重複了,會抛錯,但是如果不是同一配置檔案中,會發生覆寫。

循環引用也很好了解:A 依賴 B,而 B 依賴 A。或 A 依賴 B,B 依賴 C,而 C 依賴 A。

預設情況下,Spring 允許循環依賴,當然如果你在 A 的構造方法中依賴 B,在 B 的構造方法中依賴 A 是不行的。

之後的源碼中還會出現這兩個屬性,這裡先知道就可以了。

prepareBeanFactory

之前我們說過,Spring 把我們在 xml 配置的 bean 都注冊以後,會"手動"注冊一些特殊的 bean。

這裡簡單介紹下 prepareBeanFactory (factory) 方法:

/**
 * Configure the factory's standard context characteristics,
 * such as the context's ClassLoader and post-processors.
 * @param beanFactory the BeanFactory to configure
 */
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   // BeanFactory 需要加載類,是以需要類加載器,
   // 這裡設定為加載目前 ApplicationContext 類的類加載器
   beanFactory.setBeanClassLoader(getClassLoader());

   // 設定 BeanExpressionResolver
   beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
   //關于 屬性編輯器
   beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

   // 添加一個 BeanPostProcessor,這個 processor 比較簡單:
   // 實作了 Aware 接口的 beans 在初始化的時候,這個 processor 負責回調,
   // 這個我們很常用,如我們會為了擷取 ApplicationContext 而 implement ApplicationContextAware
   // 注意:它不僅僅回調 ApplicationContextAware,
   // 還會負責回調 EnvironmentAware、ResourceLoaderAware 等,看下源碼就清楚了
   beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

   // 下面幾行的意思就是,如果某個 bean 依賴于以下幾個接口的實作類,在自動裝配的時候忽略它們,
   // Spring 會通過其他方式來處理這些依賴。
   beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
   beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
   beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
   beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

   /**
    * 下面幾行就是為特殊的幾個 bean 指派,如果有 bean 依賴了以下幾個,會注入這邊相應的值,
    * 之前我們說過,"目前 ApplicationContext 持有一個 BeanFactory",這裡解釋了第一行
    * ApplicationContext 還繼承了 ResourceLoader、ApplicationEventPublisher、MessageSource
    * 是以對于這幾個依賴,可以指派為 this,注意 this 是一個 ApplicationContext
    */
   beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
   beanFactory.registerResolvableDependency(ResourceLoader.class, this);
   beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
   beanFactory.registerResolvableDependency(ApplicationContext.class, this);

   // 這個 BeanPostProcessor 也很簡單,在 bean 執行個體化後,如果是 ApplicationListener 的子類,
   // 那麼将其添加到 listener 清單中,可以了解成:注冊 事件監聽器
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

   // 這裡涉及到特殊的 bean,loadTimeWeaver,忽略
   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()));
   }

   /**
    * Spring它會幫我們預設注冊一些有用的 bean,
    * 我們也可以選擇覆寫
    */

   // 如果沒有定義 "environment" 這個 bean,那麼 Spring 會 "手動" 注冊一個
   if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
   }
   // 如果沒有定義 "systemProperties" 這個 bean,那麼 Spring 會 "手動" 注冊一個
   if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
   }
   // 如果沒有定義 "systemEnvironment" 這個 bean,那麼 Spring 會 "手動" 注冊一個
   if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
   }
}
           

不用每個地方都要看懂,我自己也隻能看個大概,畢竟Spring還是很龐大的,主要了解我們平常最常用的就可以了,一些其它細節可以在大緻掌握Spring 架構大概後再來進行子產品化的研究。

postProcessBeanFactory

注冊需要的BeanPostProcessor,

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
           

在AbstractApplicationContext 中是空方法(會加載一些預設的BeanPostProcessor),擴充部分交由具體的子類來實作。

invokeBeanFactoryPostProcessors

下面代碼中我們需要注意getBeanFactoryPostProcessors(),它是擷取的手動注冊的BeanFactoryPostProcessor。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

		// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
		// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
		//忽略
		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}
           

下面開始我們的大頭,看看這個invokeBeanFactoryPostProcessors中做的都是什麼,這個方法很長,其實邏輯還是很簡單的,最好自己對照着源碼看。

public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		Set<String> processedBeans = new HashSet<>();
        //判斷該beanFactory 是否是 BeanDefinitionRegistry 類型
        //BeanDefinitionRegistry是可以注冊Bean的
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					//調用postProcessBeanDefinitionRegistry方法
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}

			// Do not initialize FactoryBeans here: We need to leave all regular beans
			// uninitialized to let the bean factory post-processors apply to them!
			// Separate between BeanDefinitionRegistryPostProcessors that implement
			// PriorityOrdered, Ordered, and the rest.
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
			    //處理 PriorityOrdered 類型
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			//排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			//添加到要執行的集合中
			registryProcessors.addAll(currentRegistryProcessors);
			
			//調用 postProcessBeanDefinitionRegistry 方法
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
			    //處理 Ordered 類型
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					if (!processedBeans.contains(ppName)) {
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						processedBeans.add(ppName);
						reiterate = true;
					}
				}
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				registryProcessors.addAll(currentRegistryProcessors);
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
				currentRegistryProcessors.clear();
			}

			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			// Invoke factory processors registered with the context instance.
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let the bean factory post-processors apply to them!
		
		//擷取 BeanFactoryPostProcessor
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (processedBeans.contains(ppName)) {
				// skip - already processed in first phase above
			}
			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// Finally, invoke all other BeanFactoryPostProcessors.
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		// Clear cached merged bean definitions since the post-processors might have
		// modified the original metadata, e.g. replacing placeholders in values...
		beanFactory.clearMetadataCache();
}
           

如果 beanFactory是BeanDefinitionRegistry的執行個體,這個BeanDefinitionRegistry是可以注冊Bean的。然後處理我們手動注冊的BeanFactoryPostProcessor,周遊每一個對象,驗證是不是BeanDefinitionRegistryPostProcessor的執行個體。BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}
           

如果是BeanDefinitionRegistryPostProcessor的執行個體,那麼就強制類型轉換後,執行BeanDefinitionRegistryPostProcessor的生命周期方法

postProcessBeanDefinitionRegistry

,并且将這個BeanFactoryPostProcessor放入到registryPostProcessors容器中.

如果不是BeanDefinitionRegistryPostProcessor的執行個體,那麼直接放入到regularPostProcessors容器中。

processedBeans代表了一個已經處理過的Bean的容器,防止重複執行!

擷取到的BeanDefinitionRegistryPostProcessor類型的Bean中,如果是PriorityOrdered類型的,那麼會放入priorityOrderedPostProcessors容器中,然後排序,執行BeanDefinitionRegistryPostProcessor的生命周期方法

postProcessBeanDefinitionRegistry

。相同的方式再處理Ordered類型的,最後剩下的再單獨處理。以上三種類型的postProcessBeanDefinitionRegistry處理完後,再執行BeanFactoryPostProcessor的生命周期方法

postProcessBeanFactory

如果 beanFactory不是BeanDefinitionRegistry的執行個體

直接執行BeanFactoryPostProcessor的生命周期方法postProcessBeanFactory,将手動添加的BeanFactoryPostProcessor處理掉。

上面處理的是BeanDefinitionRegistryPostProcessor,下面我們再處理BeanFactoryPostProcessor

String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

           

處理的方式同BeanDefinitionRegistryPostProcessor一緻,先處理完PriorityOrdered,再處理Ordered,最後處理普通的,這裡要注意的是,因為BeanDefinitionRegistryPostProcessor也是BeanFactoryPostProcessor,并且他之前已經處理過了,是以這個過程就不會在處理了。

舉個例子

一個普通的BeanFactoryPostProcessor:

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    public void postProcessBeanFactory(
            ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("this is MyBeanFactoryPostProcessor -> postProcessBeanFactory......");
    }

}
           

一個普通的BeanDefinitionRegistryPostProcessor,這個BeanDefinitionRegistryPostProcessor 在 postProcessBeanDefinitionRegistry 方法中注冊上面的 MyBeanFactoryPostProcessor執行個體。

public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {

        AbstractBeanDefinition beanDefinition = new RootBeanDefinition(MyBeanFactoryPostProcessor.class);

        registry.registerBeanDefinition("myBeanFactoryPostProcessor",beanDefinition);

    }

    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

        System.out.println("this is MyBeanDefinitionRegistryPostProcessor -> postProcessBeanFactory");
    }
}
           

最後在xml 中配置bean

MyBeanDefinitionRegistryPostProcessor

<bean id="myBeanDefinitionRegistryPostProcessor" class="com.study.spring.bean.MyBeanDefinitionRegistryPostProcessor">
	</bean>
           

執行結果:

this is MyBeanDefinitionRegistryPostProcessor -> postProcessBeanFactory
//...
this is MyBeanFactoryPostProcessor -> postProcessBeanFactory......
           

這樣在BeanFactory 處理 BeanFactoryPostProcessor 時,會先處理BeanDefinitionRegistryPostProcessor ,這樣就會将MyBeanFactoryPostProcessor 注冊到BeanFactory中,這樣MyBeanFactoryPostProcessor 就會在後續進行中得到執行。

這裡隻是簡單的用了一個例子來描述 BeanFactoryPostProcessor 的處理邏輯,具體的過程可以通過代碼debug來摸索。

registerBeanPostProcessors

在處理完

BeanFactoryPostProcessors

後會注冊

BeanPostProcessors

注意這兩個差別,前者主要是面向BeanFactory的,後者主要是面向Bean的,

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
           

這裡也就不展開了,和處理 BeanFactoryPostProcessors 類似,隻是這裡注冊

BeanPostProcessors

,并沒有執行其方法,具體的執行時機是在bean執行個體化的時候,到這裡,BeanFactory中bean并沒有執行個體化,這個我們後面會分析到。

onRefresh

這是一個模闆方法,具體的還有待處理的流程交由子類來實作

finishBeanFactoryInitialization

這個方法很重要,這裡會負責初始化所有的 singleton beans,鑒于篇幅不會在本文再來分析裡面的邏輯了,文章太長看着也很累,這個就留到後面後面再來分析吧。

總結

我們來總結一下,到目前為止,可以說 BeanFactory 已經建立完成(内部使用的是DefaultListableBeanFactory),

實作了 BeanFactoryPostProcessor 接口的 Bean 都已經初始化并且其中的 postProcessBeanFactory(factory) 方法已經得到回調執行了。而且 Spring 已經"手動"注冊了一些特殊的 Bean,如 ‘environment’、‘systemProperties’ 等。

實作了BeanPostProcessor 接口的Bean都已被注冊(未執行)。

接下來就是處理國際化消息,事件,監聽器了,不過目前不是我們的重點,這些就暫時忽略了。

剩下的就是初始化 singleton beans 了,我們知道它們是單例的,如果沒有設定懶加載,那麼 Spring 會在接下來初始化所有的 singleton beans。

參考

Spring IOC 容器源碼分析

Spring 技術内幕