执行ClasspathXmlApplicationContext构造器,最终会执行到下面这个方法
Tips:大部分spring的代码中,xxx()并不是实际工作的方法,而doXxx()才是。
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
super(parent)
:执行父类构造器,parent是null,最终会按顺序执行下面4个类的构造
AbstractXmlApplicationContext->
AbstractRefreshableConfigApplicationContext->
AbstractRefreshableApplicationContext->
AbstractApplicationContext
setConfiglocation()
:把传入的配置文件路径解析
refresh()
:核心方法,实际调用的是 AbstractApplicationContext
类中的refresh()
方法。
refresh()解析
其中总共有15个步骤,除开catch的部分的步骤,有以下的操作
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 1. 准备计时,初始化各种状态标记,验证环境配置
prepareRefresh();
// 2. 创建工厂,加载BeanDefinition,这里包括xml中写入配置,以及spring核心的一些bean,例如监听器。
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3. 初始化工厂设置
prepareBeanFactory(beanFactory);
try {
// 4. 允许工厂上下文中的后置处理器
postProcessBeanFactory(beanFactory);
// 5. 调用工厂后置处理器 -- 如扫描包
invokeBeanFactoryPostProcessors(beanFactory);
// 6. 注册Bean的后置处理器
registerBeanPostProcessors(beanFactory);
// 7. 为上下文初始化消息源
initMessageSource();
// 8. 为上下文初始化事件广播器 -- spring内部的事件机制
initApplicationEventMulticaster();
// 9. 初始化其他特定的其他Bean -- 这里也是一个空方法
onRefresh();
// 10. 注册监听器
registerListeners();
// 11. 完成其他剩余的单例的bean,这是注入开始的地方
finishBeanFactoryInitialization(beanFactory);
// 12. 发布相应事件,完成refresh
finishRefresh();
}catch{
...
}
finally {
//15. 清除一些缓存
resetCommonCaches();
}
}
第2步中,会执行到AbstractRefreshableApplicationContext
类中的refreshBeanFactory()
,其中的关键步骤loadBeanDefinitions(beanFactory)
,是负责加载BeanDefinition的。
这个方法又走到了AbstractXmlApplicationContext
中,
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// 创建xml beanDefinition读取器
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// 配置读取器环境,资源加载器,解析器
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
//初始化读取器,加载BeanDefinition
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}
其中最后loadBeanDefinitions(beanDefinitionReader)
又是关键。一直跟进代码,主要以loadBeanDefinition
关键字去跳转,追踪路径。
最终会找到DefaultBeanDefinitionDocumentReader
类中的doRegisterBeanDefinitions
方法。
...
//这就是解析xml,并把xml中的bean加载进来的方法
parseBeanDefinitions(root, this.delegate);
...
跟进到这里,会对xml进行解析,最终走进processBeanDefinition
方法,在这个方法里,最终把BeanDefinition进行注册。
从这一些列步骤跳出,完成了BeanFactory的初步创建,创建工厂本身和加载xml中的bean。