ClassPathXmlApplicationContext的继承关系
ClassPathXmlApplicationContext继承了AbstractXmlApplicationContext,实现了ApplicationContext接口。BeanFactory是所有容器的顶级接口,spring中所有容器都是基于BeanFactory的。ClassPathXmlApplicationContext继承关系如下图:
创建ClassPathXmlApplicationContext实例
ClassPathXmlApplicationContext中有多个构造方法,最终都通过如下的构造方法初始化容器:
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
其中,refresh()方法完成了容器的初始化。
refresh()方法的实现分析
refresh()方法的实现代码如下
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 上下文刷新的准备工作,完成一下工作:
//1、设置启动时间、是否关闭和是否激活
//2、在上下文中初始化任何占位符属性资源
//3、验证标记为必需的属性文件是可解析的
prepareRefresh();
// 创建DefaultListableBeanFactory实例,解析xml配置文件,注册bean
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//对BeanFactory进行各种功能填充
//在此方法中,增加的支持@Qualifier与@Autowired这两个注解
prepareBeanFactory(beanFactory);
try {
// 由子类实现,可进行自定义扩展
postProcessBeanFactory(beanFactory);
// 激活BeanFactory的处理器
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// 初始化message资源
initMessageSource();
// 为这个context初始化一个事件广播器
initApplicationEventMulticaster();
// 由子类实现,初始化其他bean
onRefresh();
// 注册已实现ApplicationListener接口的Bean
registerListeners();
// 实例化所有非延迟初始化的单例模式bean
finishBeanFactoryInitialization(beanFactory);
// 完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知监听者
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();
}
}
}
obtainFreshBeanFactory()方法的实现
此方法主要作用是创建DefaultListableBeanFactory实例,解析xml配置文件,注册bean。内部调用了调用了AbstractRefreshableApplicationContext类的refreshBeanFactory()方法创建bean工厂。refreshBeanFactory()方法实现如下:
protected final void refreshBeanFactory() throws BeansException {
//如果beanfactory存在,销毁所以bean和关闭beanfactory
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//定义beanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
//将bean解析为BeanDefinition
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
refreshBeanFactory()方法中,首先判断是否存在beanfactory,如果存在,销毁所有Bean,关闭beanfactory。createBeanFactory()方法创建一个新的容器。在本方法中,最重要的是loadBeanDefinitions(beanFactory),调用这个方法解析xml配置文件,注册bean。
loadBeanDefinitions(beanFactory)方法的实现如下
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// 根据给定的BeanFactory创建一个新的 XmlBeanDefinitionReader
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// 根据上下文配置bean definition reader
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
initBeanDefinitionReader(beanDefinitionReader);
//通过beanDefinitionReader解析xml配置文件,注册bean
loadBeanDefinitions(beanDefinitionReader);
}
在XmlBeanDefinitionReader中实现了loadBeanDefinitions(beanDefinitionReader)方法,代码如下:
//省略了异常处理相关代码,主要逻辑如下
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
//从encodedResource中得到InputSource和Resource
Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
InputStream inputStream = encodedResource.getResource().getInputStream();
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
//调用此方法加载BeanDefinition
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
doLoadBeanDefinitions(inputSource, encodedResource.getResource())中,从资源文件中读取Document,并且调用registerBeanDefinitions(doc, resource)注册BeanDefinition,省略无关代码,实现如下:
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
//从resource中读取得到Document
Document doc = doLoadDocument(inputSource, resource);
//注册BeanDefinition
return registerBeanDefinitions(doc, resource);
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
}
在registerBeanDefinitions(doc, resource)方法中,BeanDefinition的注册时委托给BeanDefinitionDocumentReader的registerBeanDefinitions(doc, createReaderContext(resource))方法进行注册的。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。