ApplicationContext应用上下文体系如下:

spring源码学习--AbstractXmlApplicationContext(三)_spring


之前我们已经介绍了两个子类​​ 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;
}

}