spring源码学习--AbstractXmlApplicationContext(三)

3/8/2017来源:ASP.NET技巧人气:3230

applicationContext应用上下文体系如下:

之前我们已经介绍了两个子类 SPRing源码学习--ClassPathxmlApplicationContext(一)和 spring源码学习--FileSystemXmlApplicationContext(二),接下来我们介绍一下这两个实现类的父类AbstractXmlApplicationContext。

在AbstractXmlApplicationContext中做的操作就是对applicationContext.xml的解析操作,主要是由两个函数loadBeanDefinitions(DefaultListableBeanFactory beanFactory)和loadBeanDefinitions(XmlBeanDefinitionReader reader)中实现。

//主要是对spring注入配置文件的解析,主要使用到BeanDefinitionReader和BeanDefinitionDocumentReader两个接口相关的实现类
	@Override
	protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		// Create a new XmlBeanDefinitionReader for the given BeanFactory.
		//创建XmlBeanDefinitionReader,即创建Bean读取器,并通过回调设置到容器中去,容  器使用该读取器读取Bean定义资源
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

		// Configure the bean definition reader with this context's
		// resource loading environment.
		//为Bean读取器设置Spring资源加载器,AbstractXmlApplicationContext的  
        //祖先父类AbstractApplicationContext继承DefaultResourceLoader,因此,容器本身也是一个资源加载器 
		beanDefinitionReader.setEnvironment(this.getEnvironment());
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

		// Allow a subclass to provide custom initialization of the reader,
		// then proceed with actually loading the bean definitions.
		//当Bean读取器读取Bean定义的Xml资源文件时,启用Xml的校验机制
		initBeanDefinitionReader(beanDefinitionReader);
		//Bean读取器真正实现加载的方法
		loadBeanDefinitions(beanDefinitionReader);
	}loadBeanDefinitions中的操作实际是XmlBeanDefinitionReader来解析applicationContext.xml
 //Xml Bean读取器加载Bean定义资源 
	protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
		//获取Bean定义资源的定位
		Resource[] configResources = getConfigResources();
		if (configResources != null) {
			//Xml Bean读取器调用其父类AbstractBeanDefinitionReader读取定位  
			//的Bean定义资源
			reader.loadBeanDefinitions(configResources);
		}
		String[] configLocations = getConfigLocations();
		if (configLocations != null) {
			//Xml Bean读取器调用其父类AbstractBeanDefinitionReader读取定位  
            //的Bean定义资源
			reader.loadBeanDefinitions(configLocations);
		}
	}

简单来说AbstractXmlApplicationContext中包含了applicationContext.xml的解析操作。

完整的AbstractXmlApplicationContext源码如下:

/**
 *提供的几个方法主要是用来进行spring注入bean的配置文件进行解析,主要的操作都在父类中
 */
public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext {

	private boolean validating = true;


	
	public AbstractXmlApplicationContext() {
	}

	
	public AbstractXmlApplicationContext(ApplicationContext parent) {
		super(parent);
	}

	public void setValidating(boolean validating) {
		this.validating = validating;
	}

	//主要是对spring注入配置文件的解析,主要使用到BeanDefinitionReader和BeanDefinitionDocumentReader两个接口相关的实现类
	@Override
	protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		// Create a new XmlBeanDefinitionReader for the given BeanFactory.
		//创建XmlBeanDefinitionReader,即创建Bean读取器,并通过回调设置到容器中去,容  器使用该读取器读取Bean定义资源
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

		// Configure the bean definition reader with this context's
		// resource loading environment.
		//为Bean读取器设置Spring资源加载器,AbstractXmlApplicationContext的  
        //祖先父类AbstractApplicationContext继承DefaultResourceLoader,因此,容器本身也是一个资源加载器 
		beanDefinitionReader.setEnvironment(this.getEnvironment());
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

		// Allow a subclass to provide custom initialization of the reader,
		// then proceed with actually loading the bean definitions.
		//当Bean读取器读取Bean定义的Xml资源文件时,启用Xml的校验机制
		initBeanDefinitionReader(beanDefinitionReader);
		//Bean读取器真正实现加载的方法
		loadBeanDefinitions(beanDefinitionReader);
	}

	
	protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) {
		reader.setValidating(this.validating);
	}

	 //Xml Bean读取器加载Bean定义资源 
	protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
		//获取Bean定义资源的定位
		Resource[] configResources = getConfigResources();
		if (configResources != null) {
			//Xml Bean读取器调用其父类AbstractBeanDefinitionReader读取定位  
			//的Bean定义资源
			reader.loadBeanDefinitions(configResources);
		}
		String[] configLocations = getConfigLocations();
		if (configLocations != null) {
			//Xml Bean读取器调用其父类AbstractBeanDefinitionReader读取定位  
            //的Bean定义资源
			reader.loadBeanDefinitions(configLocations);
		}
	}

	//这里又使用了一个委托模式,调用子类的获取Bean定义资源定位的方法  
    //该方法在ClassPathXmlApplicationContext中进行实现,对于我们  
    //举例分析源码的FileSystemXmlApplicationContext没有使用该方法
	protected Resource[] getConfigResources() {
		return null;
	}

}