mini-spring-course

开篇词|“眼脑手”结合,搞定Spring框架底层原理

你好,我是郭屹,一名深耕软件开发行业30年的老兵。欢迎你跟我一起手写MiniSpring,一个mini版的Spring框架。

在正式开始学习之前,我先介绍下我自己。说起来,我与Java和Spring打交道也有二十几年了。1998年我就加入了Sun Microsystems的Java团队,担任J2EE研发工程师,并在那里了解了Java专家Rodd Johnson、James Gosling等人的思想,见识了这些行业大牛的功力。

我就像是一个跟随哥伦布船队的小船员,有幸亲眼见证了这段精彩的历史。而这些经验和知识也深深影响了我的职业生涯,目前我依然活跃在代码一线,对Java和Spring的热爱依旧不减。

而这些年我在编程的同时,也一直在坚持写作,先后出版了《认识编程》《Java编程十五讲》《三字经注解》几本书,同时也很荣幸地成为了机械工业出版社专家委员会委员。对编程和写作多年的坚持,让我在技术实践与内容分享方面逐渐形成了一个正向的循环,总是喜欢把自己在技术方面的心得和实践转化成系统的知识。为此,我先后开发了MiniSpring,MiniTomcat,MiniRedis,MiniLanguage等几款开源软件,就是希望将这些知识传递给更多的人。

希望我的讲解能为Java和Spring布道,对你有所帮助。我将从IoC容器开始,带你一步步深入,直到完成一个属于自己的MiniSpring。希望你坚持下去,迈上一个崭新的台阶,到了那时,定会体会到“胸中自有沟壑”的美妙境界。

为什么建议你学习Spring底层原理?

现在这个时代,信息过载,选择过多,技术领域中各种新技术新工具层出不穷,让初学者不知从哪里下手,甚至都不知道该不该学某些技术,产生了许多困惑。那么哪些技术是我们应该花时间花精力去好好琢磨的呢?

众所周知,Java诞生二十几年来,一直是业界的主流语言和平台。而Spring则是Java开发的事实平台,我们说用Java编程,其实是在Spring框架上编程。即便最近几年进化到用分布式架构如Spring Cloud进行开发,它的底层内核仍然是Spring框架。因此,作为专业程序员,深度理解Spring Framework是很必要和重要的。对Spring这个基础框架的理解,能让我们 以不变应万变,把握住技术快速流变中相对稳定的内核

而我们平时的工作中,大部分的时间都是在调用工具包,快速搭建出客户所需要的应用程序,没有意识到需要了解底层原理。那为什么我们还要费力了解Spring的内部结构呢?对这个常见的困惑,我是这么看待的:站在应用程序的角度,不理解所用工具的原理,不太会影响你构建应用程序的进度。但是,理解了原理,你就知道了所以然, 工作过程中会更加高效准确地使用平台工具,提高应用程序的质量,如结构的扩展性和需求变化的适应性。

俗话说,下棋找高手,弄斧到班门。在学习Spring框架的过程中,分析程序结构,阅读源代码,还能让我们体会到世界顶级程序员作品的精妙之处。我们可能达不到他们那种高度和深度,但是通过学习、模仿,也能让我们的水平有本质的提升。

更进一步,我们自己在工作中, 了解了这些底层技术,就会有意识地去借鉴这些大师们的结构,让我们自己能承担更加困难、更加复杂的工作。 比如,当我们应对各种用户需求,编写增删改查等类似程序的时候,就可以回想一下,Spring框架中是如何管理用户业务,如何抽象出Bean这个概念,以及定义Bean的生命周期的,我们可以通过模仿这种技巧,提出业务表单的概念,定义它的生命周期,然后构造一个业务框架,让用户自定义表单,注册进框架,由框架自动管理运行它。现在,市面上很多成功的OA产品就来自这个简单的模仿。

当我们的工作到达了系统框架这个级别的时候,你就会时不时地想起那些大师的作品,如Spring框架、Tomcat、JDK、Redis等等,他们如何用简洁的模型、统一的技术栈,来处理千变万化的应用。他们的设计原则和模式,他们宏大的架构考量,他们的代码技巧,会给我们丰富的养分,带领我们走向专业之路。

如何高效地掌握Spring原理?

今天,我们在学习Spring的过程中,面对的一个问题是它已经是一个庞大而复杂的体系了,虽然它是开源的,代码之下了无秘密,但是面对源代码的汪洋大海,很多技术人经常会迷失其中,因一次次的挫败而导致最后只有望洋兴叹。但是回顾历史,Spring并不是生下来就是这么庞大的,它也是从小一步步长大的。作为后来者,我们的问题是只见到了长大后的Spring,没有了解到它是怎么成长起来的。失去了这个过程,就会让学习的路径变得很艰难。

其实Spring的发明者Rodd Johnson,开头的想法很简单,只是希望有一个简单的框架让程序员专注于自己的业务开发,通过框架的配置就能让不同业务单元组合在一起。这个想法其实在Sun公司Java团队提出的EJB中就有了充分的考虑。但是Rodd Johnson认为EJB过于庞大复杂,而且是侵入式的,会对上层程序员有很多限制,他对EJB进行了激烈地批评并决心构建一个小的框架,于是跟Java团队分道扬镳,这是我当时在Sun Java团队的时候发生的故事。之后的事情就是众所周知的历史了:Java团队的掌上明珠EJB被悉尼大学的Rod Johnson这个音乐学博士单枪匹马挑下马,最后完败于Spring。

因此,本课程采用快速迭代的开发模式,从一个最简单的程序开始,一步步堆积演化,每写一小段代码,都是一个可运行的程度。 在不断迭代中完善框架功能,最终实现Spring框架的核心:IOC、MVC、JDBC Template和AOP。 在一步步的迭代过程中,将Spring的底层原理融入代码中,一层层对照Spring框架的现有结构,让原理理解起来不再困难。

我们自己动手,尽量少用现成的包,以刀耕火种的方式写程序,这可以让我们彻底地理解底层原理。希望你能够从一开始就跟我一起动手,毕竟编程说到底是一个手艺活,就是动手去写,要坚持不断地练习,就能大有成效。

我自己也是经历了这么一个过程:开始只是使用框架平台,很快到了一个瓶颈;之后就开始阅读源码,了解原理解决困惑,但是仍然处于似懂非懂的状态;后来就尝试自己动手写Spring,遇到问题想破脑袋后翻查Spring的源代码,在一遍一遍地挫折借鉴中打通关节,终于有一天豁然开朗。

我们学习MiniSpring的目标是掌握Spring框架,所以我们不会自己独创什么概念和结构,而是老老实实按照Spring的结构模仿着手写。因此我们的目录结构、包名、类名接口名、继承体系、类中的主要方法名都是原封不动照搬Spring框架的。这是为了今后你一头扎进Spring框架的源代码中的时候不至于迷失方向,能很快地畅游于Spring的大海中。

课程设计

我们MiniSpring的课程大体上分成四大部分:IoC容器、MVC、JDBC Tempalte和AOP。

熟悉Spring框架的人也知道,这四大部分就是Spring框架的核心了。学好这些,今后你扩展到更多方面也会很容易。

图片

第一部分:IoC容器

IoC容器是Spring核心中的核心,Spring抽象出Bean这个概念,用一个容器管理所有的Bean,并解决上层应用的业务对象之间的耦合问题。后面所有的特性都依赖于Bean的概念和这个容器。因此即使我们简单地说Spring框架就是一个IoC容器也未尝不可。

这个部分我们会从一个极简容器开始,逐步扩展增强,最终实现一个完整的IoC容器,包含Spring框架对应的核心功能,实现Bean的管理。基于这个核心,逐步扩展到MiniSpring的其他特性。打好这个基础,后面的学习会事半功倍。

第二部分:MVC

MVC是Spring支持Web模式的程序结构,它是基于Servlet技术实现的。基本思路是利用Servlet机制,用一个单一的Servlet拦截所有请求,然后根据请求里面的的信息把任务分派给不同的业务类处理,实现原始的MVC结构。

在这一部分,我们还会将MVC与第一部分的IoC容器结合起来,构成一个更大、更完整的框架。在一步步的构造过程中,我们会重点讲解大师们怎么逐步拆解这个Servlet的功能,把专业的事情交给专门的部件去做,最后构建成一个完整的体系。

第三部分:JDBC Template

JDBC Tempalte是Spring对数据访问的一个实现,我们会重点分析Spring的实现方法,体现Rodd Johnson对简洁实用原则的把握。这一部分,我们会学习如何提取出一个JDBC访问的模板,来固化访问数据库的流程,怎么自动绑定参数值,简化上层应用程序。在此基础之上,我们还将了解到如何通过数据库连接池提高访问性能,以及模仿MyBatis将SQL语句配置到外部文件中。

通过这部分的学习,我们可以了解到,整个JDBC Template的实现都是运用了前面IoC管理Bean的方式,将数据的访问抽象成一个个Bean,注入到系统中。由此,更能深刻体会到IoC容器的功用。

第四部分:AOP

AOP是Spring框架中实践面向切面编程的探索。面向对象和面向切面,两者一纵一横,编织成完整的程序结构。在这一部分,我们将了解到Spring AOP所采用的一个实现方式:JDK动态代理。我们会学习动态代理的原理,以及如何用这个技术动态插入业务逻辑,实现切面的特性。

最后我们将再一次看到AOP与IoC的结合,使用BeanPostProcessor自动生成动态代理。这时你就会体会到,我前面说的“IoC是Spring框架核心中的核心”。

在这一步一步的演化过程中,我们对Spring的模仿逐渐成型。我坚持一个原则,就是每一步都是可以运行的,都会有看得见的收获,你不需要辛辛苦苦等到最后才能看到成果。当然,自己动手模仿Spring,是一个难度较大的工作,风景虽好,但过程也是充满艰辛的,最后的果实属于不断探索的人。任何一个技术领域都是这样,不断练习,反复琢磨,最后才能站在山顶。

《诗经》有云:“有匪君子,如切如磋,如琢如磨”。虽然中途会遇到困难,但我希望你可以坚持学习,站到山顶,跟我一起领略Spring的风采!