Spring核心:IOC容器的实现(五)

作者: 迷途小沙弥 | 来源:发表于2017-07-21 16:36 被阅读119次

    根据定位的Bean定义资源文件,将其加载读入并转换成为Document对象:

    从前文可知,其实IOC容器的启动和FileSystemContext本身没什么关系,FileSystemContext只是在基本的IOC容器的基础上,增加了与他相关的特性,而IOC容器的启动(refresh方法),是在AbstractApplicationContext(FileSystemXmlApplicationContext的基类)中执行。

    refresh方法-------描述了-----ApplicationContext的初始化过程(BeanFactory的更新,MessageSource和PostProcessor的注册......)

    refresh的过程:

    第一步:创建IOC容器,调用了obtainFreshBeanFactory方法,在这个方法中调用了子类AbstractRefreshableApplicationContext的refreshBeanFactory()方法,而这个方法,才是真正的创建BeanFactory。

    refreshBeanFactory:

    if判断:如果已经有容器存在,则需要把已有的容器销毁和关闭,以保证在refresh之后使用的是新建立起来的IoC容器。

    customizeBeanFactory():对IoC容器进行定制化,如设置启动参数,开启注解的自动装配等

    loadBeanDefinitions():调用载入Bean定义的方法,主要这里又使用了一个委派模式,在当前类中只定义了抽象的loadBeanDefinitions方法,际的载入过程其实是在AbstractRefreshableApplicationContext的子类AbstractXmlApplicationContext中实现。

    loadBeanDefinitions:


    new XmlBeanDefinitionReader(factory):创建Bean读取器,并通过回调设置到容器中去,容器使用该读取器读取Bean定义资源。

    setResourceLoader():为Bean读取器设置Spring资源加载器,父类AbstractApplicationContext继承DefaultResourceLoader,因此,容器本身也是一个资源加载器,所以这里可以使用this关键字。

    setEntityResolver():为Bean读取器设置SAX xml解析器

    initBeanDefinitionReader():当Bean读取器读取Bean定义的Xml资源文件时,启用Xml的校验机制

    loadBeanDefinitions():Bean读取器真正实现加载的方法

    首先得到BeanDefinition信息的Resource定位

    直接调用XmlBeanDefinitionReader来读取,具体的载入过程是委托给BeanDefinitionReader完成的。(理由:因为这里的BeanDefinition是通过XML文件定义的,所以应该使用XmlBeanDefinitionReader来载入BeanDefinition)

    XmlBeanDefinitionReader中的loadBeanDefinitions:


    调用AbstractBeanDefinitionReader中的loadBeanDefinitions方法。主要是对定位Resource资源计数,计算Resource资源的数量

    调用BeanDefinitionReader类中的loadBeanDefinitions方法。但是,这个方法是一个模板方法(接口方法),具体的实现在XmlBeanDefinitionReader中。

    重载方法,调用下面的loadBeanDefinitions(String, Set);方法

    getResourceLoader():获取在IoC容器初始化过程中设置的资源加载器

    getResources():将指定位置的Bean定义资源文件解析为Spring IoC容器封装的资源,加载多个指定位置的Bean定义资源文件

    loadBeanDefinitions():委派调用其子类XmlBeanDefinitionReader的方法,实现加载功能

    else方法内(XmlBeanDefinitionReader通过调用其父类DefaultResourceLoader的getResource方法获取要加载的资源):

    将指定位置的Bean定义资源文件解析为Spring IoC容器封装的资源,加载单个指定位置的Bean定义资源文件

    DefaultResourceLoader的getResource():

    判断如果是带有classpath标识的Resource,就通过相应方法处理

    否则:处理带有URL标识的Resource

    从这里我们可以知道:FileSystemXmlApplicationContext容器提供了getResourceByPath方法的实现,就是为了处理既不是classpath标识,又不是URL标识的Resource定位这种情况。

    当获取完Resources之后,就要调用XmlBeanDefinitionReader的loadBeanDefinitions方法。

    XmlBeanDefinitionReader加载Bean定义资源(获取到Resource之后):


    将读入的XML资源进行特殊编码处理 载入XML形式Bean定义资源文件方法

    this.resourcesCurrentlyBeingLoaded.get();获取线程局部变量

    encodedResource.getResource().getInputStream():将资源文件转换为IO输入流

    doLoadBeanDefinitions:具体读取过程

    doLoadDocument():将XML文件转换为DOM对象,解析过程由documentLoader实现

    registerBeanDefinitions():启动对Bean定义解析的详细过程,该解析过程会用到Spring的Bean配置规则

    getValidationModeForResource():获取XML文档验证类型

    createDocumentBuilderFactory():创建DocumentBuilderFactory对象工厂(创建文件解析器工厂)

    createDocumentBuilder():从对象工厂中获取DocumentBuilder对象()。

    parse():解析包含了encodedResource资源信息的inputSource

    创建文件解析器工厂:


    DocumentBuilderFactory.newInstance():创建文档解析工厂

    factory.setValidating(true);设置解析XML的校验

    至此Spring IoC容器根据定位的Bean定义资源文件,将其加载读入并转换成为Document对象过程完成。

    相关文章

      网友评论

        本文标题:Spring核心:IOC容器的实现(五)

        本文链接:https://www.haomeiwen.com/subject/mkwlkxtx.html