【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的生命周期
【Spring源码分析】四、ClassPathXmlApplicationContext的Bean的加载_第1张图片【Spring源码分析】四、ClassPathXmlApplicationContext的Bean的加载_第2张图片

五、get Bean

这个是和XmlBeanFactory一模一样。

你可能感兴趣的:(Spring学习)