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 ...
随机推荐
- CSS3让长单词与URL地址自动换行——word-wrap属性
div{ word-wrap:break-word; } word-wrap属性可以使用的属性值为normal与break-word两个.使用normal属性值时浏览器默认处理,只在半角空格或者连字符 ...
- JavaSE(六)包装类、基本类型和字符串之间的转换、==和equals的区别
一.包装类 Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的,这在实际使用时存在很多的不便,为了解决这个不足, 在设计类时为每个基本数据类型设计了一个对应的类进行代表,这 ...
- NYoj_104最大和
最大和 时间限制:1000 ms | 内存限制:65535 KB 难度:5 描述 给定一个由整数组成二维矩阵(r*c),现在需要找出它的一个子矩阵,使得这个子矩阵内的所有元素之和最大,并把这个子矩 ...
- 用于 C♯ 图像识别的轮廓分析技术
用于 C♯ 图像识别的轮廓分析技术 供稿:Conmajia 标题:Contour Analysis for Image Recognition in C# 作者:Pavel Torgashov 此中文 ...
- Document类型知识大全
Document类型 1.文档的子节点 Document类型可以表示HTML页面或者其他基于XML的文档.不过,最常见的应用还是作为HTMLDocument实例的document对象.通过这个文档对 ...
- 用adb录制手机屏幕视频
adb shell screenrecord命令可以用来录制Android手机视频 screenrecord是一个shell命令,支持Android4.4(API level 19)以上,支持视频格式 ...
- HTML meta refresh 刷新与跳转(重定向)页面
下面为各位整理了一些HTML meta refresh 刷新与跳转(重定向)页面的例子吧,后面本站长自己也补充了一些js页面刷新与跳转例子吧. refresh 属性值 -- 刷新与跳转(重定向)页 ...
- iptabes的用法
iptables的用法 基本用法: iptables [-t table] [subcommand] chain [rulenum] [options...] [match] [target] ipt ...
- <script>的用法
<script> </script> 是指 在 HTML 页面中插入一段 JavaScript
- oracle11g安装教程(注意事项及图文教程)
Oracle安装与重装注意事项 1.安装oracle(**) 注意:安装Oracle之前确定自己的主机(计算机)名要保证计算机名是英文的. 1.oracle的安装文件不要放在含有中文的目录当中,如:d ...