读《Spring 源码深度解析》随记

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了读《Spring 源码深度解析》随记相关的知识,希望对你有一定的参考价值。

    bean 是Spring 中最核心的东西,因为Spring就像是个大水桶,而bean就像是容器中的水,水桶脱离了水便也没什么用处了。  

    一、核心类:

    1.DefaultListableBeanFactory

    XmlBeanFactory 继承自 DefaultListableBeanFactory ,而 DefaultListableBeanFactory 是整个bean加载的核心部分,是 spring 注册及加载 bean 的默认实现,而对于 XmlBeanFactory 与 DefaultListableBeanFactory 不同的地方其实在 XmlBeanFactory 中使用自定义的 XML 读取器 XmlBeanDefinitionReader,实现了个性化的 BeanDefinitionReader 读取。

    2. XML 配置文件的读取是 Spring 中重要的功能 ,因为Spring的大部分功能都是以配置作为切入点的,那么我们可以从 XmlBeanDefinitionReader 中梳理一下资源文件读取、解析及注册的大致脉络。

  (1)通过继承自 AbstractBeanDefinitionReader 中的方法,来使用 ResourLoader 将资源文件路径转换为对应的 Resource 文件。

  (2)通过 DocumentLoader 对 Resource 文件进行转换,将 Resource 文件转换为 Document 文件。

  (3)通过实现接口 BeanDefinitionDocumentReader 的 DefaultBeanDefinitionDocumentReader 类对 Document 进行解析,并使用 BeanDefinitionParserDelegate 对 Element 进行解析。

 

    二、容器的基础 XmlBeanFactory

    分析下面一行代码如何实现的:

    BeanFactory bf =  new XmlBeanFactory(new ClassPathResource("beanFactoryTest.xml"));

    //TODO 插入图2-7

   1.配置文件的封装

   这里插一句:在日常开发的工作中,资源文件的加载也是经常用到,可以直接使用 Spring 提供的类,比如在希望加载文件时可以使用以下代码:

          Resource resource = new ClassPathResource("beanFactoryTest.xml");

          InputStream inputStream = resource.getInputStream(); 

    

   XmlBeanFactory.java

      public XmlBeanFactory(Resource resource) throws BeansException {

            this(resource,null);

      }

      public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException{

           super(parentBeanFactory);

           this.reader.loadBeanDefinitions(resource);

      }

     上面函数中的代码 this.reader.loadBeanDefinitions(resource) 才是资源加载的真正实现,也是我们分析的重点之一。我们可以看到时序图中提到的 XmlBeanDefinitionReader 加载数据就是在这里完成的。

    2.加载Bean

    首先我们看一下 this.reader.loadBeanDefinitions(resource) 方法的时序图

    //TODO 图2-9

   public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException{

         return loadBeanDefinitions(new EncodedResource(resource));

   }

   public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException{

       ...

       return doLoadBeanDefinitions(inputSource, encodedResource.getResource());

       ...

   }

    真正核心处理部分 doLoadBeanDefinitions(inputSource, encodedResource.getResource())

    protected int doLoadBeanDefinitions (InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {

        try{
               int validationMode = getValidationModeForResource(resource);//获取对 XML 文件的验证模式。

               Document doc = this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler, validationMode,                                        isNamespaceAware());//加载 XML 文件,并得到对应的 Document。

               return registerBeanDefinitions(doc, resource);//根据返回的Document 注册 Bean 信息。(这部逻辑非常复杂,下次讨论)

       }catch(){

     ...   

       }

     }    

        

 

以上是关于读《Spring 源码深度解析》随记的主要内容,如果未能解决你的问题,请参考以下文章

读《Spring源码深度解析》途中问题1

Spring源码深度解析pdf

Spring Boot Bean 解析

Spring源码深度解析-《源码构建》

Spring读源码系列02----默认标签解析过程

深度解析Spring源码编译Spring源码(spring5.2.x版本)