谈谈Spring中IOC容器的启动流程

408 阅读4分钟

谈谈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.第十二步,完成上下文的刷新工作,清除缓存,发布容器刷新完成事件等