谈谈Spring中IOC容器的启动流程
以XML容器ClassPathXmlApplicationContext为例子来讲述,注解则是AnnotationConfigApplicationContext
ClassPathXmlApplicationContext中有refresh方法(这个方法也是IOC容器启动的关键) ,refresh方法有十几个子方法,以下会一一解释
1.prepareRefresh():处理容器刷新前的预处理工作
- 设置容器启动时间
- 设置一些状态位标识
- 初始化占位符属性资源(eg:$)
- 创建环境对象,校验必填属性是否可解析
- 初始化一些成员变量(eg:earlyApplicationListeners、earlyApplicationEvents)
2.obtainFreshBeanFactory():创建DefaultListableBeanFactory工厂,给bean工厂设置一些属性,加载配置文件信息,封装成bean定义信息
- 创建bean工厂,类型是DefaultListableBeanFactory
- 设置bean工厂的序列化ID
- 定制化bean工厂(也是设置属性,如是否允许重写allowBeanDefinitionOverriding、是否允许循环依赖allowCircularReferences)
- 加载bean定义信息、初始化BeanDefinitionReader读取器,通过SAX解析XML文件,封装成BeanDefinition,注册到DefaultLisableBeanFactory中的beanDefinitionMap中(XML方式才有读取与SAX解析这一步)
3.prepareBeanFactory(beanFactory):设置bean工厂一些属性,如添加一些BeanPostProccessor增强器等(Spring容器通过BeanPostProcessor给了我们一个机会对Spring管理的bean进行再加工。)
- 设置bean类加载器信息
- 添加一些BeanPostProcessor增强器
- 忽略一些接口的自动装配依赖
- 注册一些bean对象到容器中,如environment,systemProperties等
4.postProcessBeanFactory(beanFactory):留给子类扩展实现,是一个模板方法
5.invokeBeanFactoryPostProcessors(beanFactory):执行BeanFactoryPostProcessor的postProcessBeanFactory()增强方法
6.registerBeanPostProcessors(beanFactory):注册BeanPostProcessor增强器,注意到这里只是注册,真正是在初始化阶段的前后执行
7.initMessageSource:初始化MessageSource(也就是国际化处理)
8.initApplicationEventMulticaster():初始化应用事件多播器
- 如果容器中存在applicationEventMulticaster,则直接获取,否则会创建一个新的SimpleApplicationEventMulticaster并注册到容器中
9.onRefresh():模板方法,留给子类扩展实现
- 在单例对象实例化之前,允许子类做一下扩展
10.registerListeners():注册一些监听器
- 往applicationEventMulticaster事件多播器中注册一系列监听器
11.finishBeanFactoryInitialization(beanFactory):最重要的方法,IOC容器创建最重要的一个步骤,完成非懒加载的单例bean对象的实例化,包括反射创建bean对象,属性填充,循环依赖处理,bean的初始化等等
- 循环遍历之前解析后的BeanDefinition定义信息
- 通过反射创建bean对象
- bean的属性填充(populateBean方法)
- 调用Aware接口相关方法,如BeanNameAware、BeanFactoryAware等
- 执行BeanPostProcessor的postProcessBeforeInitialization()前置增强方法
- 执行initializingBean的afterPropertiesSet()方法
- 执行自定义的初始化方法
- 执行BeanPostProcessor的postProcessAfterInitialization()后置增强方法
- 执行DisposableBean的destroy()销毁方法
- 执行自定义的销毁方法
12.finishRefresh():完成容器刷新完成后的一些处理工作
- 清除资源缓存
- 初始化生命周期处理器,调用onRefresh()刷新方法
- 发布容器已刷新事件
总结:Spring中IOC容器启动主要是在AbstractApplicationContext#refresh()方法实现的,大体过程如下
1.第一步,首先会执行一些容器刷新前的准备工作,如设置容器启动时间,一些状态标志位等
2.第二步,创建容器对象,其实就是实例化DefaultListableBeanFactory对象,这一步包含了bean定义信息的解析,解析后的属性都封装到了DefaultListableBeanFactory的成员属性中,如我们常见的beanDefinitionMap、beanDefinitionNames
3.第三步,准备Bean工厂,实际上就是设置beanFactory一些属性
4.第四步,Spring提供了postProcessBeanFactory()方法给我们扩展,我们可以注册一些特殊的后置处理器等操作
5.第五步,执行BeanFactoryPostProcessor后置处理器的增强方法
6.第六步,注册BeanPostProcessor后置处理器
7.第七步,为上下文初始化MessageSource,即国际化处理
8.第八步,初始化事件多播器,为后面的事件发布监听做准备
9.第九步,提供了模板方法onRefresh()留给子类初始化其他bean
10.第十步,注册Listener监听器
11.第十一步,也是最关键的一步,实例化所有剩下的非懒加载的单例Bean,Bean的生命周期也是这里开始的
- 具体说,就是这里会获取到之前解析的所有bean名称集合,挨个调用getBean(beanName)方法,然后经历doGetBean()、createBean(),doCreateBean()创建bean的流程,接着会通过反射创建出bean实例对象,然后进行populateBean()属性填充,填充完后会进行bean的初始化,初始化过程主要执行Aware接口方法,执行初始化方法,回调后置增强器的方法等
12.第十二步,完成上下文的刷新工作,清除缓存,发布容器刷新完成事件等