【Spring源碼分析】四、ClassPathXmlApplicationContext的Bean的加載

一、介紹

ClassPathXmlApplicationContext具有XmlBeanFactory的所有功能,自我感覺他就是XmlBeanFactory擴展。

二、代碼切入點

 @Test
    public void testApplicationContext(){
        applicationContext = new ClassPathXmlApplicationContext("bean.xml");
        User user = applicationContext.getBean("user", User.class);
        user = applicationContext.getBean("user", User.class);
    }

三、分步驟分析

  • 這步驟主要就是保存路徑和分析路徑中的佔位符。重中之重就是refresh方法。
public ClassPathXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {
		super(parent);
		setConfigLocations(configLocations);
		if (refresh) {
			refresh();
		}
	}
  • 這個方法寫的真是行雲流水,讓看代碼的人能很快的梳理整個結構,我認爲這是spring最優雅的代碼之一
public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				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.
				destroyBeans();

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

				// Propagate exception to caller.
				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() {
		……
		//設計模式--模板方法的使用
		// Initialize any placeholder property sources in the context environment.
		initPropertySources();

		// Validate that all properties marked as required are resolvable:
		// see ConfigurablePropertyResolver#setRequiredProperties
		getEnvironment().validateRequiredProperties();

		……
	}
  • obtainFreshBeanFactory該方法就是獲取BeanFactory。
    在開始的時候說ClassPathXmlApplicationContext具有XmlBeanFactory的所有功能,主要就是在這個方法中體現的。它相當於把XmlBeanFactory組合進去了
protected final void refreshBeanFactory() throws BeansException {
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
		    //使用的就是DefaultListableBeanFactory 
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			beanFactory.setSerializationId(getId());
			customizeBeanFactory(beanFactory);//定製beanfactory,這個算是進行擴展,而且子類也可以重寫這個方法,這就是spring開放式設計
			loadBeanDefinitions(beanFactory);//在子類中實現
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}
  • prepareBeanFactory該方法主要是加載classloader和註冊一些後置處理器,增加spel和屬性解析器等等

  • postProcessBeanFactory 該方法是個空實現,會提供你一個BeanFactory參數。

  • invokeBeanFactoryPostProcessors 執行beanFactory級別的後置處理器,這個最高級別的後置處理器

@FunctionalInterface
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;

}

BeanFactoryPostProcessor 這個類的功能,就是bean的定義已經加載好,還沒有初始化,這個時候你可以驗證bean的定義或者修改bean的定義。

  • registerBeanPostProcessors 這個方法是註冊容器級的後置處理器:這個包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 這兩個接口實現,一般稱它們的實現類爲“後處理器”
  • initMessageSource: 國際化資源處理
  • initApplicationEventMulticaster: spring的event進行事件監聽,ApplicationEventMulticaster會持有監聽器集合
  • onRefresh:這是個空方法,子類可以進行重寫
  • registerListeners:把監聽器註冊到ApplicationEventMulticaster上面
  • finishBeanFactoryInitialization:把那些非懶加載的bean直接實例化
  • finishRefresh:這個目前不知道用處

四、Sping bean生命週期

從上面的源碼分析,很容易能得到spring的生命週期
在這裏插入圖片描述在這裏插入圖片描述

五、get Bean

這個是和XmlBeanFactory一模一樣。

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