IOC容器的初始化

96 阅读2分钟

src=http___img.it610.com_image_product_eb2b2217af864820902cf7a476e6218d.jpg&refer=http___img.it610.webp
本文已参与「新人创作礼」活动,一起开启掘金创作之路。

Spring中,IOC容器的初始化分成三个步骤:资源文件定位、bean的加载和注册。

资源文件定位

我们以FileSystemXmlApplicationContext的资源定位为例,它是在DefaultResourceLoader的getResource方法中实现,如果是以classpath定位,就返回ClassPathResource,如果是以URL定位,就返回UrlResource,否则就从FileSystemXmlApplicationContext中覆写的getResourceByPath方法中获取,返回FileSystemResource。

这是DefaultResourceLoader的getResource方法: 这里写图片描述

这是FileSystemXmlApplicationContext中覆写的getResourceByPath方法: 这里写图片描述

bean的加载和注册

在spring中,会将资源文件中的bean解析成BeanDefinition,这其中,主要是经由下面几个步骤完成:

  1. 创建BeanFactory
  2. 根据BeanFactory创建BeanDefinitionDocumentReader
  3. 在BeanDefinitionDocumentReader使用loadBeanDefinitions进行bean的加载
  4. 将资源文件转换为Document,并创建BeanDefinitionDocumentReader
  5. 创建BeanDefinitionParserDelegate,并在BeanDefinitionParserDelegate中解析Document,将bean转换成BeanDefinition对象,最后再封装成BeanDefinitionHolder对象
  6. 使用BeanDefinitionReaderUtils将BeanDefinition对象添加到一个ConcurrentHashMap中,完成注册。

实例解析

接下来,我们以FileSystemXmlApplicationContext为例,进行IOC容器初始化源码解读。

  1. 在FileSystemXmlApplicationContext构造器中调用refresh方法启动IOC容器初始化 这里写图片描述

  2. refresh方法在AbstractApplicationContext中实现 这里写图片描述

  3. 接下来进入obtainFreshBeanFactory方法中创建BeanFactory 这里写图片描述

  4. 进入AbstractRefreshableApplicationContext的refreshBeanFactory方法。如果容器中已存在BeanFactory,就要先摧毁掉。 这里写图片描述

  5. 进入AbstractXmlApplicationContext的loadBeanDefinitions方法,创建XmlBeanDefinitionReader 这里写图片描述

  6. 进入loadBeanDefinitions,开始使用XmlBeanDefinitionReader进行bean的加载和注册 这里写图片描述

  7. 进入AbstractBeanDefinitionReader的loadBeanDefinitions方法 这里写图片描述

AbstractBeanDefinitionReader的loadBeanDefinitions(String) 这里写图片描述

AbstractBeanDefinitionReader的loadBeanDefinitions(String, Set) 这里写图片描述 这里写图片描述

AbstractBeanDefinitionReader的loadBeanDefinitions(Resource[]) 这里写图片描述

8.接下来进入XmlBeanDefinitionReader的loadBeanDefinitions 这里写图片描述

9.在XmlBeanDefinitionReader的doLoadBeanDefinitions里,将资源文件转换为Document 这里写图片描述

10.进入registerBeanDefinitions里,创建BeanDefinitionDocumentReader,并用来进行bean的加载和注册 这里写图片描述

进入DefaultBeanDefinitionDocumentReader的registerBeanDefinitions 这里写图片描述

11.进入doRegisterBeanDefinitions,创建BeanDefinitionParserDelegate 这里写图片描述

进入DefaultBeanDefinitionDocumentReader的parseBeanDefinitions,开始解析Document 这里写图片描述

12.进入parseDefaultElement中,我们看bean的解析过程 这里写图片描述

13.进入DefaultBeanDefinitionDocumentReader的processBeanDefinition,这里使用BeanDefinitionParserDelegate解析bean后返回BeanDefinitionHolder,再用BeanDefinitionReaderUtils进行注册 这里写图片描述

14.我们先进入BeanDefinitionParserDelegate的parseBeanDefinitionElement,看bean的解析过程 这里写图片描述

进入BeanDefinitionParserDelegate的parseBeanDefinitionElementparseBeanDefinitionElement,在这里会先将bean解析成AbstractBeanDefinition,然后将AbstractBeanDefinition封装到BeanDefinitionHolder后返回 这里写图片描述 这里写图片描述

15.接下来进入BeanDefinitionParserDelegate的parseBeanDefinitionElement,这里会具体解析xml文件中,每个bean节点的信息,包括class,property,parent等,里面的具体解析过程,大家自己去看哈。 这里写图片描述 这里写图片描述

16.回到13,我们到BeanDefinitionReaderUtils的registerBeanDefinition看bean的注册过程。这里会调用BeanDefinitionRegistry进行注册,然后将BeanDefinitionHolder中的beanName与别名关联起来。 这里写图片描述

17.我们看SimpleBeanDefinitionRegistry中的registerBeanDefinition,他的注册过程就是将BeanDefinition存储在一个ConcurrentHashMap中。 这里写图片描述

以上就是一个完整的IOC容器初始化过程。