正文
阅读之前要注意的东西:本文就是主打流水账式的源码阅读,主导的是一个参考,主要内容需要看官自己去源码中验证。全系列文章基于 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 虽然已经废弃不建议使用,但是作为学习,并没有太大问题。
从命名风格上看,我们可以看到几个频率非常高的单词,本系列文章中,这些关键词将密集且高频率出现:
来一句不论不类的串讲:Spring 负责将 Bean的[配置/定义] ,自动化 的 注册 到 Bean工厂 中,以供我们在自己的业务逻辑代码里调取。
说不伦不类吧,但是好像有又那么一点点味道了。
依据这些关键词再去梳理类图,不难发现这是一个有向无环图,那么我们可以在起点和终点之间拆出多条路径来。
2 类图介绍
我们先把图中的,类和接口负责的功能,简单介绍一下,篇幅会很长,但是我真心觉得很重要:
虽然类图中的继承关系比较复杂,实际上我们关注的是我们的成品 "Bean工厂"
- XmlBeanFactory
- 可以把它理解为:Bean的加工厂 + 仓库,程序运行的过程中随机某个时刻,我们需要某个Bean ,那么去找厂方索要该 Bean即可
需要理解该类图的本质是:从顶层的:BeanFactory 开始,随着继承层次不断加深,BeanFactory 接口的功能被不断的丰富,就像在不停的叠buff,直到最终成长为我们期望的:
2.1 顶层 类/接口介绍
实际上 spring.beans 最核心的 东西都在如下4个 类/接口 里了。 【这里是按照个人的学习习惯划分的,官方没有这种说法。】
在 XmlBeanFactory 的类图中,处于这4个 接口/类 ,下层继承链路上的 接口/类 大多都只是做了功能上的丰富。
- AliasRegistry:Alias 直译为别名、化名等;组合起来就是,别名/化名的注册
- 实际上这里对应的是我们在xml文件中配置的 bean名称/bean别名 处理相关的操作:注册、校验等等
- BeanFactory:观察如下图所示的方法,不难看出它主要的作用是提供对bean的管理功能
- BeanDefinitionRegistry 字面意思,类定义注册表?
- 再看详细方法,就是对 类定义信息 的增、删、查、校验操作
- 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 拓展 类/接口 介绍
坐稳了,加速了
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 中定义方法
- ConfigurableListableBeanFactory:
- 看下边的方法清单,我们关注它新增的方法,主要包含对 "Bean工厂" 的配置的操作相关方法
3 尾声
为啥要单独成一个章节呢?
终于接近尾声了:
- DefaultListableBeanFactory:
- 可以回过头去看上边的类图,万流归海了,有木有?
- 可以认为 DefaultListableBeanFactory 具备了上述接口、抽象类提到的所有功能
- 别名管理功能
- Bean [配置/定义] 管理
- bean 实例对象管理
- 支持单例 [缓存管理]
- BeanFactory 的基础上增加 parentFactory 的支持
- BeanFactory 的配置管理
- 支持自动配置功能:自动创建Bean、初始化、自动注入、自动后置处理
下边,到最后一个类了
- XmlBeanFactory:
- 只看方法清单,新增的方法寥寥无几
- 实际上 XmlBeanFactory 所做的事情,就只是在 DefaultListableBeanFactory 的基础上,拓展了从 XML 文件中读取 BeanDefinition[Bean 定义] 的功能
这里花了很长的篇幅介绍类图,我感觉吃透这个类图还是挺重要的。