Spring源码解析一(框架梳理)
整体架构
打算开始写这个系列,不为上首页,也不为博取多少关注,只有一个目的:梳理知识,扩充思路;废话不多,开始吧。第一步,大家去spring的官方github下面去下载它的源码,具体的自己谷歌,我已经下下来了,然后spring的源码分为下面几个部分:

哈哈,大家是不是有一种头晕目眩的感觉,没事,我带你来分析源码,顺便给自己也做个总结。第一步是要理清楚各个层级关系之间的依赖,我把图画好,大家自己看看就好。所有的依赖都可以在gradle文件里面找到。为了效率,建议大家在idea里面下载一个插件,叫做gradle view,可以像Maven一样查看依赖树。其中大家接触的比较多的就是compile和optional了,compile对应的是当前项目的模块,而optional对应第三方依赖。其他的我相信用过maven的人都能理解。

如果是本项目的其他模块的话,会有一个project的关键字在里面,如下面的代码,画了思维导图,用XMind画的,今天就到这里吧,可累死我了。具体的XMind文件请到这里下载。大家如果想看大图,可以右键在新窗口打开图片,这样就清楚了。
compile(project(":spring-beans"))
compile(project(':spring-core'))

那么继续,大家是不是有一种无从下手的感觉呢?有这种感觉就对了,因为你并不知道哪块是对你重要的,我的建议就是:选依赖项少的,并且被依赖项多的模块来作为首要模块来进行分析,大家可以打开项目自己去看看,我个人认为spring-core这个比较核心,而且其他的很多的项目都要依赖到这个模块,那么我们就从这个模块入手吧。当然并不是要大家一上来就把所有的细节都研究清楚,我们现在能做的,只是把模块和模块之间的架构关系理清楚,还没有深入到细节。我们打开spring-core可以发现有如下模块:

虽然说我也不知道哪个模块应该先去研究,不过依靠我直觉应该是core模块,下面的分析都是基于core模块向四周进行辐射。core包里面又有很多的子包,并且还有一堆类,虽然我现在并不知道这些类是做什么的。碰到这里,大家怎么进行分析呢?告诉大家一点方法:通过用法来进行分析,大家如果之前看过一些spring相关的文章,介绍里面的一些原理的文章,我觉得都可以回忆一下,因为这些文章所说到的思路,也许就是你正在寻找的答案。我这里是在分析架构,因为架构和架构是耦合在一起的而并非独立的个体,所以我的叙述很可以不会按照默认顺序来进行叙述,敬请理解。
AliasRegistry
Spring给这个类的一个解释就是《通用的别名管理器》,我们想一想:Spring当中什么是别名?Qualifier注解!那么我们来寻找一下,是否这个AliasRegistry和Qualifier有什么不可告人的秘密。因为Qualifier是一个注解,所以我要找和注解相关的实现类。AnnotationConfigApplicationContext,我们首先思考一个问题:AnnotationConfigApplicationContext和AliasRegistry是否存在直接的关系呢?我们可以回到这个问题,Qualifier注解是用在什么上面的?什么?这还用问,当然是Bean上面啊!于是乎,就有了下面的答案:

AliasRegistry其实你可以理解为一个抽象基接口,其实真正的用到的接口是BeanDefinitionRegistry,那么AnnotationConfigApplicationContext其实是被GenericApplicationContext所继承了,而GenericApplicationContext又实现了BeanDefinitionRegistry,并且这几个呗实现的方法,其内部结构都是交给了一个BeanFactory的工厂类,也就是我们常常说到的Spring的IOC相关的思想。
@Override
public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
this.beanFactory.removeBeanDefinition(beanName);
} @Override
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
return this.beanFactory.getBeanDefinition(beanName);
}
是不是有点迷迷糊糊了?想睡觉了?别急,我画一张思维导图给大家醒醒脑,具体的思维导图可以到这里下载,如果有出错的地方,还请各位批评指正。

像上面这么分析的话,实在是太慢了,我需要找到一个可行的方法,尽快分析。大家其实也应该想到,利用网络,我们可以快速搜集到相关的知识点。有点小小的无奈,因为网上并没有详细的解答,可能是大家编程都只满足于会用就行了吧,真的太失望了。那么我还是从我认为的比较有代表性的类来跟大家分析吧。
MethodParameter
那么大家肯定会有一个疑问,这个MethodParameter到底是做什么的呢?从下面的图中,我们可以看到具体的子类实现,大部分是在messaging下面的。虽然说我不是很想跟大家去分析细节,不过我觉得这也是没办法的事情啊,因为细节就在那里,逃不掉的。

首先在这个类里面定义了一个私有的成员,叫做Executable,这个Executable可来头不小,它是Method的父类,也就是java.lang.reflect包里面的那个我们常常用到的Method.第二个成员变量是parameterIndex,还有一个参数是nestingLevel(内嵌级别),这个参数我暂时还没搞懂是做什么的,不过spring给出的官方解释是:the nesting level of the target type,它有一个为1的默认值。并且这3个成员变量组成了一个构造函数。
private final Executable executable;
private final int parameterIndex;
private int nestingLevel = ;
public MethodParameter(Method method, int parameterIndex, int nestingLevel) {
Assert.notNull(method, "Method must not be null");
this.executable = method;
this.parameterIndex = validateIndex(method, parameterIndex);
this.nestingLevel = nestingLevel;
}
虽然我们现在还不知道这个类是做什么的,不过Java我认为有一大优势就是它可以通过语义来猜这个类的用法,不像C++一样指针遍地飞,找不到方向;下面的代码就是这个类的属性,大家也许会说,我还没看到这个类的具体用法,我怎么可能知道这些属性是做什么的呢?非也非也,做事就是要有探索精神,编程不能吃老本,前人的经验固然重要,但是你的经验,你的直觉就不重要了吗?所以相信自己哦!
@Nullable
private volatile Class<?> containingClass; @Nullable
private volatile Class<?> parameterType; @Nullable
private volatile Type genericParameterType;
@Nullable
private volatile Annotation[] parameterAnnotations; @Nullable
private volatile ParameterNameDiscoverer parameterNameDiscoverer; @Nullable
private volatile String parameterName; @Nullable
private volatile MethodParameter nestedMethodParameter;
我们来想这么一个问题,然后把这些问题串联起来,我有一个Method(方法),方法里面有一些参数(MethodParameter),这些参数不止一个,它可能是第一个,第二个参数(parameterIndex),每一个参数都有一个类型object.class(parameterType),参数前面有可能加上了注解(parameterAnnotation,并且这个注解可能还有多个),这个参数有它自己的名字,因为这个方法可能是一个复杂类型,所以可能有内部类,内部类当中可能有嵌套方法参数-nestedMethodParameter(还有待考证)当然还有一种可能性就是泛型当中可能还有泛型,这样层层嵌套,参见这篇文章,总之在答案出来之前,我不武断认为我的就是正确的。我画了一幅思维导图来总结一下自己的思路。文件可以在这里下载。

再来看一张更详细的图,这是从AttributeAccessor接口开始的。

Spring源码解析一(框架梳理)的更多相关文章
- Spring源码解析-ioc容器的设计
Spring源码解析-ioc容器的设计 1 IoC容器系列的设计:BeanFactory和ApplicatioContext 在Spring容器中,主要分为两个主要的容器系列,一个是实现BeanFac ...
- spring 源码解析
1. [文件] spring源码.txt ~ 15B 下载(167) ? 1 springн┤┬вио╬Ш: 2. [文件] spring源码分析之AOP.txt ~ 15KB 下载( ...
- Spring源码解析之BeanFactoryPostProcessor(三)
在上一章中笔者介绍了refresh()的<1>处是如何获取beanFactory对象,下面我们要来学习refresh()方法的<2>处是如何调用invokeBeanFactor ...
- Spring源码解析 - AbstractBeanFactory 实现接口与父类分析
我们先来看类图吧: 除了BeanFactory这一支的接口,AbstractBeanFactory主要实现了AliasRegistry和SingletonBeanRegistry接口. 这边主要提供了 ...
- Spring源码解析——循环依赖的解决方案
一.前言 承接<Spring源码解析--创建bean>.<Spring源码解析--创建bean的实例>,我们今天接着聊聊,循环依赖的解决方案,即创建bean的ObjectFac ...
- Spring源码解析系列汇总
相信我,你会收藏这篇文章的 本篇文章是这段时间撸出来的Spring源码解析系列文章的汇总,总共包含以下专题.喜欢的同学可以收藏起来以备不时之需 SpringIOC源码解析(上) 本篇文章搭建了IOC源 ...
- Spring源码解析之PropertyPlaceholderHelper(占位符解析器)
Spring源码解析之PropertyPlaceholderHelper(占位符解析器) https://blog.csdn.net/weixin_39471249/article/details/7 ...
- Spring源码解析之ConfigurationClassPostProcessor(二)
上一个章节,笔者向大家介绍了spring是如何来过滤配置类的,下面我们来看看在过滤出配置类后,spring是如何来解析配置类的.首先过滤出来的配置类会存放在configCandidates列表, 在代 ...
- Spring源码解析之八finishBeanFactoryInitialization方法即初始化单例bean
Spring源码解析之八finishBeanFactoryInitialization方法即初始化单例bean 七千字长文深刻解读,Spirng中是如何初始化单例bean的,和面试中最常问的Sprin ...
- spring源码解析前瞻
很多人有疑问:为什么要读源码?读源码有什么用?我也一直问自己这些问题,读源码非常枯燥,工作中又用不到,慢慢的自己读源码越发现自己知识的不足,无法把知识串起来,形成知识体系.从单系统中常用的Spring ...
随机推荐
- 深入理解 react-router 路由系统
作者:范洪春链接:https://zhuanlan.zhihu.com/p/20381597来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 在 web 应用开发中,路由 ...
- dp水一天
水一些dp的联系题 标签: dp ###hdu_2045 题意 一穿珠子,用三种颜色染色,要求相邻的珠子和两端的珠子不能是同一种颜色,求当有n个珠子的时候有几种染色方案 题解 表示dp[i][j][k ...
- HDU1016(素数环)
Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- net+Oracle开发过程中遇到的小问题
最新的项目开始使用Oracle后,5个月之间遇到一些在SqlServer中没有遇到的问题,这里记录并贴上一些常用的解决办法. Oracle相关 一.数据库不同版本还原: 刚开始我们一直使用Oracle ...
- 【新版】Android技术博客精华汇总
[新版]Android技术博客精华汇总(原文链接内持续更新) http://www.apkbus.com/thread-313856-1-1.html Kotlin Kotlin学习资料汇总 http ...
- echarts自定义提示框数据
tooltip: { trigger: "axis", axisPointer: { // 坐标轴指示器,坐标轴触发有效 type: "line" // 默认为 ...
- Core Animation 文档翻译(第三篇)
Core Animation 文档翻译(第三篇) 设置Layer对象 当我们使用核心动画时,Layer对象是一切的核心.Layers 管理我们APP的可视化content,Layer也提供了conte ...
- block的修饰词为什么选用copy
想必很多开发人员知道一般用copy修饰block,接下来就讲解为什么需要用copy,甚至会讲到其实用strong修饰block也是可以的 在 Objective-C 语言中,一共有 3 种类型的 bl ...
- WPF 简单的循环GIF播放
//MVVM要事件绑定,记得项目引用类库“Sysrem.Windows.interactivity”,然后XAML引用 xmlns:i="http://schemas.microsoft.c ...
- Linux apache的运行用户和用户组
我们在安装apache后,有时在上传文件的时候,提示没有权限或者是不可写,我们都会去查文件夹的权限. 通过ls -l /var/www/html/website可以很直观的看出我们文件和文件夹的权限, ...