《系列一》-- 2、XmlBeanFactory 的类图介绍.md




阅读之前要注意的东西:本文就是主打流水账式的源码阅读,主导的是一个参考,主要内容需要看官自己去源码中验证。全系列文章基于 spring 源码 5.x 版本。



Spring源码阅读系列--全局目录.md



引子

1、容器最基本使用.md

系列1 - bean 标签解析:

2、XmlBeanFactory 的类图介绍.md

3、XmlBeanFactory 对xml文件读取.md

4、xml配置文件解析之【默认】命名空间【标签】的解析.md

5、xml配置文件解析之【自定义】命名空间【标签】的解析.md

系列2 - bean 获取: getBean() 做了什么

前言

本文可以浓缩为一句话:

从 BeanFactory 进化为 XmlBeanFactory的过程中,究竟套娃继承了哪些类和接口:

  • 这些接口分别定义了什么功能
  • 这些类分别实现了哪些功能

1 XmlBeanFactory 类图概览

不知道你有没有被吓到,我肯定被吓到了。这么长的类图,感觉还没入门就要入土了。

颤抖之余,我觉得我还是可以挣扎一下的。

这个类图底端从 XmlBeanFactory起始,到顶部的 AliasRegistry、BeanFactory 结束

XmlBeanFactory 继承自spring.beans 的核心组件:DefaultListableBeanFactory;

XmlBeanFactory 虽然已经废弃不建议使用,但是作为学习,并没有太大问题。

从命名风格上看,我们可以看到几个频率非常高的单词,本系列文章中,这些关键词将密集且高频率出现:

  • Bean 这个肯定不能直译了,我比较喜欢的一个朴素的说法是:

    • bean是计算机自动生成的类,bean是一个由Spring IoC容器实例化、组装和管理的 对象
  • BeanFactory

    • 直译:Bean 工厂
  • Registry

    • 直译:注册表,类图里有三个重要的Registry
      • SingletonBeanRegistry: 单例 bean 的注册和管理
      • AliasRegistry: bean 的别名注册和管理
      • BeanDefinitionRegistry: bean 配置的注册和管理
  • BeanDefinition

    • 直译:Bean定义,我更愿意把它看成是 Bean 配置
  • Autowire

    • 直译:自动xx

来一句不论不类的串讲:Spring 负责将 Bean的[配置/定义]自动化注册Bean工厂 中,以供我们在自己的业务逻辑代码里调取。

说不伦不类吧,但是好像有又那么一点点味道了。

依据这些关键词再去梳理类图,不难发现这是一个有向无环图,那么我们可以在起点和终点之间拆出多条路径来。

2 类图介绍

我们先把图中的,类和接口负责的功能,简单介绍一下,篇幅会很长,但是我真心觉得很重要:

虽然类图中的继承关系比较复杂,实际上我们关注的是我们的成品 "Bean工厂"

  • XmlBeanFactory
    • 可以把它理解为:Bean的加工厂 + 仓库,程序运行的过程中随机某个时刻,我们需要某个Bean ,那么去找厂方索要该 Bean即可

需要理解该类图的本质是:从顶层的:BeanFactory 开始,随着继承层次不断加深,BeanFactory 接口的功能被不断的丰富,就像在不停的叠buff,直到最终成长为我们期望的:

  • XmlBeanFactory

2.1 顶层 类/接口介绍

实际上 spring.beans 最核心的 东西都在如下4个 类/接口 里了。 【这里是按照个人的学习习惯划分的,官方没有这种说法。】

在 XmlBeanFactory 的类图中,处于这4个 接口/类 ,下层继承链路上的 接口/类 大多都只是做了功能上的丰富。

  • AliasRegistry:Alias 直译为别名、化名等;组合起来就是,别名/化名的注册
    • 实际上这里对应的是我们在xml文件中配置的 bean名称/bean别名 处理相关的操作:注册、校验等等

  • BeanFactory:观察如下图所示的方法,不难看出它主要的作用是提供对bean的管理功能

  • BeanDefinitionRegistry 字面意思,类定义注册表?
    • 再看详细方法,就是对 类定义信息 的增、删、查、校验操作
      • 所谓类定义,可以理解是bean.xml 中定义的一些元数据

        spring 对xml 配置的解析结果,也是通过 BeanDefinition 类来承载的。

        • 比如bean的字段、方法上设置
        • 参与spring容器生命周期的:init(),destroy() 等方法。
        • 类-全限定路径/名称
        • 。。。。 下文将对其详细展开

  • SingletonBeanRegistry:直译为,对单例Bean的注册
    • 下图是该接口定义的一系列方法,可以做个推测:它做的事情就是根据Name维护了一组单例 bean

整点潦草,且天马行空的:

// todo

这是我理解的这几个头部接口的关系:

  • 从 xml 配置得到类定义 ,BeanDefinitionRegistry 负责管理 bean.xml 定义的 元数据信息

  • 从类定义信息梳理出别名,AliasRegistry 负责管理:bean 和 bean的别名的关联关系

  • 根据类 BeanDefinition 可以实例化出bean的实例,并通过 BeanFactory 进行维护

  • 而 AliasRegistry 和 BeanFactory 的关系呢,更像是一个键值对卡表

    • 维护着bean和 bean的 Alias(别名) 之间的关系,我们从工程里要获取bean的时候,可以通过别名获取。
      • factory.getBean("BeanName")
      • factory.getBean("Bean_AliasName")
  • 而 SingletonBeanRegistry 更像是一个阀门,如果工厂需要支持单例,就需要实现该接口

我们现在有了框架了,基于这个框架再去看各个拓展的 类/接口

2.2 拓展 类/接口 介绍

坐稳了,加速了

  • SimpleAliasRegistry:没啥好说的,AliasRegistry 接口最的基本实现

    • 同理,类图也用不着放了
  • DefaultSingletonBeanRegistry:同样,没啥好说的,单例bean注册表:SingletonBeanRegistry 接口最的基本实现

    • 同理没图

todo

  • HierarchicalBeanFactory
    • 它的定义简单得让人心疼,它其实也就一个功能
      • 它在最初的 BeanFactory 接口的基础上增加了对 ParentFactory 的支持
        • 我理解是,一个bean 可以被:存在继承关系多个BeanFactory 解析。
          就像我们平时,就算覆写了超类的方法,实际上也很少将超类方法逻辑直接短路,大部分时候都是会继承超类方法的执行结果的。

  • ListableBeanFactory
    • 查看它的方法清单 和 接口注释,可以简单梳理下它的功能:
      • 拓展 BeanFactory,支持:根据条件获取Bean的配置清单
        • 在类的注释上,提到了配置的预加载,它增加的是:对 BeanFactory 管理的的BeanDefinition 的增强。

  • FactoryBeanRegistrySupport
    • 它继承自 DefaultSingletonBeanRegistry,在其基础上,增加了 对 FactoryBean 的支持。
      • 比如,我们看截图的第一个方法,它的作用是判断给定的FactoryBean 的类型,那么可以遇见,我们在调用getBean(beanName),获取bean时,如果Spring容器发现 xml配置的是 FactoryBean 而非普通bean时,就会通过
        FactoryBeanRegistrySupport 接口相关的方法进行处理。

  • ConfigurableBeanFactory
    • 如果实现了该接口,我们的 "bean 工厂" 将会在原基础上,增加各种帮助配置 Factory 的方法
      • 看下边图里的一些列setXxx 方法就可以窥见一些东西了,这里包含很多的配置项设置
        • BeanFactory的各种配置的:Setter + Getter

  • AbstractBeanFactory
    • 其实这个类并没有新增什么比较独特的功能,它主要负责的为前边提到的接口提供,一些必要方法的实现
    • 其实回过头去看,它的继承体系,你可以发现,它上层的某几条继承分支,全是接口,我们前边说的那一堆增量功能,大部分都还没人实现呢。。。
      • 实际上,AbstractBeanFactory 是个抽象类,它也只是实现了上述接口的一部分内容,有些功能的实现可能还在更下边的类中,才得到落地。
    • 最后,看看标注的类注释,其实对功能的归纳已经比较清晰了

  • AutowireCapableBeanFactory
    • 这个接口为我们的 "Bean工厂" 增加的是自动配置功能,自动创建Bean、初始化、自动注入、自动后置处理<堪称神器,后续AOP相关章节会仔细探讨>
      • 比如我们现在广泛使用的,通过注解定义bean的方式,跟这个接口就息息相关。

  • AbstractAutowireCapableBeanFactory
    • 这是个抽象类,它继承自 AbstractBeanFactory,并实现了 自动配置接口 AutowireCapableBeanFactory 中定义方法
      • 在接口 AutowireCapableBeanFactory 中定义了:支持自动配置的 "Bean工厂",需要有哪些方法。

        最终到了抽象类 AbstractAutowireCapableBeanFactory 这里,才提供了具体的实现

  • ConfigurableListableBeanFactory
    • 看下边的方法清单,我们关注它新增的方法,主要包含对 "Bean工厂" 的配置的操作相关方法
      • 它包含的配置有:指定忽略的类型以及接口,等等

3 尾声

为啥要单独成一个章节呢?

终于接近尾声了:

  • DefaultListableBeanFactory
    • 可以回过头去看上边的类图,万流归海了,有木有?
    • 可以认为 DefaultListableBeanFactory 具备了上述接口、抽象类提到的所有功能
      • 别名管理功能
      • Bean [配置/定义] 管理
      • bean 实例对象管理
      • 支持单例 [缓存管理]
      • BeanFactory 的基础上增加 parentFactory 的支持
      • BeanFactory 的配置管理
      • 支持自动配置功能:自动创建Bean、初始化、自动注入、自动后置处理

下边,到最后一个类了

  • XmlBeanFactory
    • 只看方法清单,新增的方法寥寥无几
      • 实际上 XmlBeanFactory 所做的事情,就只是在 DefaultListableBeanFactory 的基础上,拓展了从 XML 文件中读取 BeanDefinition[Bean 定义] 的功能

这里花了很长的篇幅介绍类图,我感觉吃透这个类图还是挺重要的。

posted @ 2023-04-06 23:56  bokerr  阅读(85)  评论(0编辑  收藏  举报