如何阅读Spring源码
主要内容:
- 必要的知识储备
- 让扁平的文字立体起来
- 画中有话
- “黄老师脸盲,看谁都能想到明星”
- 源码阅读的几个原则
必要的知识储备
去年(2018)我花了很多时间在SSM上面,因为和大部分人一样,面对一大堆配置我感到手足无措,不知道什么是什么,也不知道它为什么起作用。
其实归根到底,我们之所以学不明白SSM,觉得隔靴搔痒,个人认为是因为“配置式开发”和我们之前“编码式开发”差别太大了。不论是xml还是注解,和我们平时写的业务代码相去甚远。作为一个开发人员,当你看到一个切实的功能被实现了,而自己却完全看不到for循环和if判断的身影,心里是不踏实的。对于一个“手艺人”,唯一能让我们感到踏实的,是if else for这样的编码,而不是@Aspect、@Controller这样的配置!
找到症结以后,我去重新学习了注解、反射、动态代理等知识,然后又学了一遍SSM框架,这回视野就开阔多了。下面是我复习时顺便写的博客,相信对有同样困扰的朋友有帮助:
- 浅谈反射机制
- 注解(上)
- 注解(下)
- 浅谈JDK动态代理(上)
- Java 动态代理作用是什么?
- 浅谈JDK动态代理(下)
- Listener(倾听者)
- ContextLoaderListener解析
- Spring AOP的实现原理 ?
- Filter实现全站编码
- servlet的本质是什么,它是如何工作的?
- Servlet(下)
但是当时仍然不敢去看Spring源码,因为我心里会觉得:哇,Spring源码诶,我才一年经验,肯定看不懂吧。
很多时候,一件事的失败并不是外部条件多么艰难,而仅仅是因为你怕,所以这个可能伟大的念头干脆都尚未发生就流产了。
促使我发生改变的是尚硅谷雷丰阳老师的《Spring注解驱动开发》。原先我其实仅仅把它当做一个普通的Spring视频学习,因为我那会儿对Spring各种注解还是不是特别熟悉。这套视频前面确实都是基础内容,教你每个注解大概什么作用。但是到了中后期,突然笔锋一转分析起了源码。一开始当然不适应,但是整套视频看完,就对“源码”两个字麻木了...
于是开始将魔爪伸向了Spring。
让扁平的文字立体起来
前阵子《破冰行动》挺火的,给大家介绍一下人物关系:
广东省东山市有一个禁毒模范村,叫塔寨。它的村主任叫林耀东,他有个弟弟叫林耀华。塔寨是一个宗祠观念很重的村落,人口一万多,大多姓林。为了便于管理,族人大致被分为三派:一房、二房、三房。林耀东管一房、弟弟林耀华管二房,三房由林宗辉管理。林耀东有一个儿子叫林景文,林耀华也有一个儿子,叫林灿。林宗辉有一个女儿和两个儿子,分别叫林大宝、林二宝、林三宝。
介绍完反派势力,讲讲警方。主角叫李飞,他父亲是赵嘉良,赵作为卧底和林耀东接触。李飞还有一个干爹李维民,是本次扫毒行动总指挥,同时是赵嘉良的上司,两个人暗中通信多年、亲密无间。李飞有一个高中同学叫蔡军,蔡军是东山市刑警大队的,他老婆是林宗辉的女儿林大宝,也是他高中同学。
老实说,我当初第一次看《破冰行动》,有点分不清人物关系,随着剧情的展开才慢慢了解。但是,我现在有办法让你在一分钟内理清人物关系:

当然,这个还是不够直观,换种表现形式:

举《破冰行动》并不是说它有多好看,而是想说:相较文字这种扁平化的信息流,我们的大脑更喜欢结构化、成片的东西,记忆更深刻。
同样的,我在学习雷丰阳老师的《Spring注解驱动开发》时,一开始只是用txt做一些简单的记录。可是到了后面就跟不上了,而且发现之前做的笔记自己也看不懂了。因为写下那些文字的时候,基本就是照抄老师的,并没有在脑子做分类和结构化处理。
后来第二次复习时,改用思维导图后感觉好多了:

画中有话
经常看我专栏的朋友都知道我其实是一个艺术家,在知乎我可以说画画比我好的不懂技术,懂技术的画画没我好,两者都懂的没我帅。
能用一张图说明白的我基本不会浪费笔墨去讲一大堆,这样读者没什么耐心。


我的专栏文章,随处可见这样的草图。个人觉得这些草图可以迅速直观地帮初学者建立对该知识点的第一印象,具体的细节留待后面再补充,而不是一开始就劈头盖脸甩过去一大堆概念。
同样的,Spring源码做了很多层抽象,类与类之间有时层级非常深。如果非要在有限的篇幅里告诉读者各种继承关系,那会使得文章读起来味同嚼蜡,也会挫伤初学者的积极性。所以我还是选择用图来简化:

具体的继承关系,他们自己去阅读源码时自然会注意到,无需我多嘴。
不要让博客抢了API的活,这是我个人的观点。
“黄老师脸盲,看谁都能想到明星”
这句话其实是朋友对我脸盲的吐槽。说来也奇怪,我在学习上也经常“脸盲”,善于发现知识点之间的联系。

在我看来,知识点与知识点之间是存在联系的,有些甚至只是同一个知识点的“变种”。就像你去砍树,你要是执着于砍各种枝干和树叶,那么估计要砍到天黑。较为聪明的办法是,发现它们的共性知识点,抓住本质。一旦抓住本质,记忆将会变得轻松,直接起手就是砍树根,一下子就砍倒搬回家了。
总之,发散思维多联想,善于抓住共性内容。
源码阅读的几个原则
- 忌漫无目的
Spring源码成百上千万行,你必须带着目的去看源码,不然看到一半可能都不知道这个方法是干嘛的。
- 一定要Debug
Debug的好处是,随时随地观察内存中变量的情况。程序说到底是为了处理数据的,数据体现在一个个变量上。通过观察变量的改变,推测每个方法的大致作用,是非常有效的源码阅读技巧。
- 善用方法调用栈
不论是Eclipse还是IDEA,Debug时左侧都会出现方法调用栈。在你感兴趣的地方打一个断点,就能知道程序经过了哪些类、几个方法到这里的。这对理清调用过程很有帮助。

- 先整体后局部、大方法之后再小方法
不要一开始就掉进一个个小方法的调用链中,这样子出不来的。
先观察变量的变化,猜测主干方法做了啥,在逐一验证,查看小方法
最后,并不是所有人都需要阅读源码,也不是一定要看得非常非常精,不放过每一句,没必要。阅读源码的最终落脚点一定是:帮助我们更好地使用Spring。
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。