当前位置 博文首页 > 文章内容

    一个简单的Spring容器初始化流程详解

    作者:shunshunshun18 栏目:未分类 时间:2021-01-23 14:43:41

    本站于2023年9月4日。收到“大连君*****咨询有限公司”通知
    说我们IIS7站长博客,有一篇博文用了他们的图片。
    要求我们给他们一张图片6000元。要不然法院告我们

    为避免不必要的麻烦,IIS7站长博客,全站内容图片下架、并积极应诉
    博文内容全部不再显示,请需要相关资讯的站长朋友到必应搜索。谢谢!

    另祝:版权碰瓷诈骗团伙,早日弃暗投明。

    相关新闻:借版权之名、行诈骗之实,周某因犯诈骗罪被判处有期徒刑十一年六个月

    叹!百花齐放的时代,渐行渐远!



    前言

    首先我们初始化一个最简单的容器,用这个容器研究初始化的流程。

    下面就是一个再简单不过的IoC容器了,该容器包含了一个名为beanA的bean,我们初始化容器后,取出该Bean,并调用方法。

    public class BeanA {
     private String testStr = "Test";
     public BeanA(){
      System.out.println("Running A");
     }
     public void sayHello(){
      System.out.println("I'm beanA.");
     }
    }
    
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
     <bean id="beanA" class="cn.jirath.learn.spring.BeanA">
     </bean>
    </beans>
    
    @Test
    void testHello(){
     Resource springResource=new ClassPathResource("spring-beans.xml");
     BeanFactory beanFactory=new XmlBeanFactory(springResource);
     BeanA beanA= (BeanA) beanFactory.getBean("beanA");
    	beanA.sayHello();
    }
    

    虽然XmlBeanFactory已经被Spring标记为过时,但是为了达到我们从一个xml定义的bean信息构造一个BeanFactory的目的,勉为其难,还是先用一下233。

    这段代码很简单,但是反映了我们使用IoC的一个基础流程:

    1. 选择并构建数据源
    2. 利用数据源构建一个容器
    3. 取出Bean使用

    我们就先从这几点一点点讲

    在开始之前,需要意识到的是:Spring作为一款优秀的面向对象的框架设计,Spring中采用了大量的设计模式并按照面向对象的逻辑对各个类进行设计,做到了各个类功能单一。

    这意味着,Spring的代码会有一种剥洋葱的感觉,子类对双亲扩展,调用默认实现。

    选择并构建数据源

    构建数据源的部分难度不大,会稍微简单点讲

    这里推荐一本书:《Spring源码深度解析(第2版)》

    看了Spring的设计,这是真的面向对象。

    Spring一开始是使用大量的xml文件配置了容器。从面向对象的角度思考,为了方便使用,需要将各种资源都被抽象出来,先看一下他的资源类结构体系。该部分是系统最底层,在core包中

    InputStreamSource封装能返回InputStream的类,可以返回这个流。

    日常开发用Spring的体系也会很便捷。

    Resource体系达到了这样的目的:对于不同的文件来源都有一种实现来读取该文件,同时,拥有一个规范的接口。

    现在我们有了Resource的设计,为了读取对象,Spring提供了BeanDefinitionReader、ResourceLoader来从资源中提取出我们需要的资源内容。这些类的关系如下:

    1. Resource代表一个资源对象
    2. ResourceLoader将文件转化为Resource对象
    3. DocumentLoader将Resource对象转化为Document对象
    4. BeanDefinitionDocumentReader解析Document对象为BeanDefinitions
    5. BeanDefinitionReader抗了初始化的大梁,在new的时候会绑定一个Bean定义注册器(DefaultListableBeanFactory实现了他),后面解析后会用这个注册器注册

    这就是大致的一个逻辑,把握住这个大致的逻辑看源码,体验要上升不少

    下面是最上方的例子启动的大致的流程,大量的代码在处理读取资源的逻辑

    1. Resource代表一个资源对象
    2. Resource封装为带编码格式的EncodedResource对象
    3. XmlBeanDefinitionReader构建Document对象
    4. XmlBeanDefinitionReader内部有个DocumentLoader,读取Resource对象转化为Document对象
    5. ResourceLoader将文件转化为Resource对象
    6. DocumentLoader将Resource对象转化为Document对象
    7. Document对象转为Element对象
    8. DocumentReader读取Element对象,将信息存储在BeanDefinitionParserDelegate
    9. DocumentReader解析BeanDefinitionParserDelegate为BeanDefinitionHolder
    10. BeanDefinitionHolder获取BeanDefinitions,交给register进行注册(加锁、放map)。
    11. 返回注册的数量

    这里就是初始化的结果了

    总结