spring启动源码分析(ClassPathXmlApplicationContext)
Applicantioncontext uml图

- ClassPathXmlApplicationContext xml 配置文件项目中的路径
- FileSystemXmlApplicationContext xml 配置文件在系统中的路径
- AnnotationConfigApplicationContext 注解类启动方式
BeanFactory uml图

- ApplicationContext 继承了 ListableBeanFactory,这个 Listable
的意思就是,通过这个接口,我们可以获取多个 Bean,大家看源码会发现,最顶层 BeanFactory 接口的方法都是获取单个 Bean
的。 - ApplicationContext 继承了 HierarchicalBeanFactory,Hierarchical
单词本身已经能说明问题了,也就是说我们可以在应用中起多个 BeanFactory,然后可以将各个 BeanFactory设置为父子关系。 - AutowireCapableBeanFactory 这个名字中的 Autowire 大家都非常熟悉,它就是用来自动装配 Bean用的,但是上图ApplicationContext 并没有继承它。为了使用它,ApplicationContext 接口定义中的最后一个方法 getAutowireCapableBeanFactory()
- ConfigurableListableBeanFactory 也是一个特殊的接口,看图,特殊之处在于它继承了第二层所有的三个接口,而ApplicationContext 没有。这点之后会用到。
spring启动基本流程
- 调用spring容器准备刷新的方法,记录启动时间,设置active属性为true,closed为false;
- 初始化任务占位符属性
- 校验xml配置文件格式,
- 如果存在beanFactory和Bean,则删除,并创建DefaultListableBeanFactory
- 设置是否允许bean覆盖和循环引用
- 分割成xml数组,循环每一个xml配置文件,使用Threadlocal保证线程安全。
- inputStream读取xml配置文件并转为document对象(DeferredDocumentImpl),并从document对象获取DocumentElement并转为element对象(DeferredElementNSImpl)
- 获取element对象的ChildNodes(为Bean数组)并遍历该对象(有转回element类型)
- 分析每个element对象的bean定义元素,并封装成BeanDefinitionHolder,设置BeanDefinition,beanName,aliases[]别名数组。
- 根据beanName对Bean进行注册,处理重复beanName(是否允许循环引用);保存beanDefinitionMap<beanName,beanDefinition>;保存beanDefinitionNames保存在list;manualSingletonNames保存在LinkedHashSet;并注册bean别名 。
- (1)设置 BeanFactory 的类加载器,(2)初始化当前 ApplicationContext 的 MessageSource,(3)初始化当前 ApplicationContext 的事件广播器,(4)注册事件监听器,监听器需要实现 ApplicationListener 接口,
- 初始化Bean流程。
- 停止bean 定义解析、加载、注册;
- 循环beanDefinitionNames,对非抽象、非懒加载的 singleton Bean。
- 广播事件,ApplicationContext 初始化完成。
源码分析流程
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
prepareRefresh();
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
try {
postProcessBeanFactory(beanFactory);
invokeBeanFactoryPostProcessors(beanFactory);
registerBeanPostProcessors(beanFactory);
initMessageSource();
initApplicationEventMulticaster();
onRefresh();
registerListeners();
finishBeanFactoryInitialization(beanFactory);
finishRefresh();
}
catch (BeansException ex) {
destroyBeans();
cancelRefresh(ex);
throw ex;
}
}
}