开端

挺多技术都还是会过时的,但是Spring作为一套功能十分强大的全家桶框架,地位很难被撼动,甚至我已经后悔之前的项目使用了Shiro作为权限控制框架而不是Spring Security。原本是打算进军Spring Cloud,然后直接上手毕业设计,但是回顾我曾经的学习路线,挺多知识都只是囫囵吞枣式的学习,并没有一个系统、全面、深度的掌握。

比如我是先学的Spring Boot,再去学的Spring,是不是挺奇葩的。这就和先学了三年级的方程求解,再去学一年级的加减法算术一样。我确实已经会用方程求解了,但是直接将两个数字放在等号同一边的这种正向思维式的解题方式还是没有学会,我只会反向思维的方程求解。如果要完全掌握计算,必须不管正反都理解它的原理才行。所以我才打算,重新来过,从Spring开始,吃透源码。

所以这一方面我肯定会写很多篇博文,今天的全文都只算是一篇开端。

The importance of 源码

如果只是使用一个框架,那叫会看。但是如果能读懂源码,那叫会读。如果还能结合相关算法和设计模式,那叫会写。作为一位合格的Java后端架构师,需要具备有写框架这方面的能力。然而阅读源码费时费力,且普及程度非常差,许多简单的应用其实是环环相扣,层层嵌套得来的,并且还会遇到过于老旧而完全不清楚为什么要这么写的情况。

无论如何,放弃阅读源码还是不明智的。俗话说,读万卷书,行万里路。其实各种框架之间也有很多共同之处,当你认真读完Spring的源码,或许理解其他框架会快很多。

或许我写的内容并不会十分全面,毕竟写下这些最主要的还是为了做一个学习笔记。但是也希望读到这些博文的你会有所收获,因为写在这里的都是精华。

核心实现

整体架构

Spring是一个分层框架,大约分为20个模块,总体可以归纳为以下几个部分。

Core Container

核心容器包含Core、Beans、Context、Expression Language模块,前两者为基础部分,提供IOC和依赖注入特性。

Core:核心工具类,其他组件都需要用到。

Bean:包含访问配置文件、创建管理Bean的类。

Context:提供类似于JNDI注册器的框架式对象访问方法,继承了Beans的特性,支持J2EE,关键接口是ApplicationContext。

Data Access/Integration

该层包含JDBC、ORM、OXM、JMS和Transaction模块。

Web

该模块建立在应用程序上下文模块之上。包含以下几个模块:

Web模块:使用servlet listener初始化IOC容器。

Web-Servlet模块:包含MVC实现,使代码和web forms之间能够清楚地分离开。

Web-Struct模块:提供了用于Portlet环境和Web-Servlet模块的MVC的实现。

AOP

Aspects模块:提供对AspectJ的集成支持。

Instrumentation模块:提供对class instrumentation和classloader的实现。

容器

基本用法

如果说Spring是一个水桶,Beans就是水桶中的水,在正式开始源码分析之前,有必要了解一下其核心的两个类。

  • DefaultListableBeanFactory

    这是加载Bean的核心部分,是Spring注册及加载Bean的默认实现,XmlBeanFactory继承自它并且使用了自定义的XML读取器XmlBeanDefinitionReader实现个性化读取。这个类的层次结构较为复杂,分为以下几个:

    AliasRegistry:定义对alias的简单增删改等操作。

    SimpleAliasRegistry:使用map缓存,实现AliasRegistry接口。

    SingletonBeanRegistry:定义对单例的注册及获取。

    DefaultSingletonBeanRegistry:对前一个类函数的实现。

    FactoryBeanRegistrySupport:在DefaultSingletonBeanRegistry基础上增加了对FactoryBean的特殊处理功能。

    BeanFactory:定义获取Bean及Bean的各种属性。

    HierarchicalBeanFactory:继承前一个类,增加了对parentFactory的支持。

    BeanDefinitionRegistry:定义BeanDefinition的增删改操作。

    ConfigurableBeanFactory:提供配置Factory的各种方法。

    ListableBeanFactory:根据各种条件获取Bean 的配置清单。

    AbstractBeanFactory:综合FactoryBeanRegistrySupport和ConfigurableBeanFactory的功能。

    AutowireCapableBeanFactory:提供创建Bean、自动注入、初始化以及应用Bean的后处理器。

    AbstractAutowireCapableBeanFactory:综合人AbstractBeanFactory并对接口AutowireCapableBeanFactory实现。

    ConfigurableListableBeanFactory:BeanFactory配置清单,指定忽略类型及接口等。

    DefaultListableBeanFactory:综合上面所有功能,主要是对Bean注册后的处理。

  • XmlBeanDefinitionReader

    XML配置文件的读取是Spring中重要的功能,因为Spring的大部分功能都是以配置作为切入点的,我们也来看看各个类的功能。

    ResourceLoader:定义资源加载器,主要应用于根据给定的资源文件地址返回对应的Resource。

    BeanDefinitionReader:主要定义资源文件读取并转换为BeanDefinition的各个功能。

    EnvironmentCapable:定义获取Environment方法。

    DocumentLoader:定义从资源文件加载到转换为Document的功能。

    AbstractBeanDefinitionReader:对EnvironmentCapable、BeanDefinitionReader类定义的功能进行实现。

    BeanDefinitionDocumentReader:定义读取Document并注册BeanDefinition功能。

    BeanDefinitionParserDelegate:定义解析Element的各种方法。

结果分析,我们可以得出XmlBeanDefinitionReader中主要包含以下几步的处理:

  1. 使用ResourceLoader将资源文件路径转换为对应的Resource文件。
  2. 通过DocumentLoader对Resource文件进行转换,将Resource文件转换成Document文件。
  3. 通过实现接口BeanDefinitionDocumentReader对Document进行解析,并使用BeanDefinitionParserDelegate对Element进行解析。

弃更

写到这,我感觉Spring的源码实在是太过于复杂了。关于前几篇文章,都是我深刻理解之后写下的总结性博文,而学习Spring源码明显吃力很多,只能照办书中的文字,代码量也非常多。我认为单单把重要的内容摘抄下来并不能帮助到大家,所以Spring源码方面的博文不出意外地话就停止更新了。但我依旧会去学一遍,可能等我全部看完,才能再写一篇总结性的文章。

最后修改:2022 年 05 月 27 日
随意