本文很少涉及spring源码的相关内容,旨在提供一个不错的源码阅读的方法。
在此之前,笔者也多次试图搭建源码阅读环境,都不得而终
希望本文能给喜欢阅读源码的朋友们一些帮助
环境搭建:
jdk 1.7
idea
maven
搭建spring application:
知其然方能之其所以然,我们先来搭建一个基于spring的demo程序。笔者使用的IDE提供模板程序创建功能,直接创建一个新的spring程序。(没有该功能可手动补全pom文件--见附图)
代码:
spring的容器(context)配置项
<context:annotation-config/>
开启注解功能(笔者偏好注解)
<context:component-scan base-package="com.nd">
基础包配置(应用启动context会扫描加载基础包下的bean)
bean组件创建
新建一个bean组件,并且加上注解@Component,这样容器在初始化的时候会扫描该组件,并且加入到容器中。
main函数
首先通过xml配置文件初始化容器(context),然后在容器中获取bean,调用bean的sayHello()方法并打印。
结果输出:
进入正题——源码阅读方法
源码阅读,从打印出Hello world! 才真正开始。学习过spring的小伙伴们都知道,spring的核心就是Ioc,也就是容器(代码中的ApplicationContext)。
很多关于spring的书里都是这么形容spring的,spring提供了一个容器,就像是一个装满水的水桶,水桶里的水,就是容器中管理的bean。有了context(容器)和bean(组件),才有了后面各种强大的功能如DI、AOP等。因此,我们首要的目的,就是探索spring的容器和组件,以及容器是如何管理这些组件的。
下载源码
查看AppicationContext,发现是一个已经编译过的.class文件,也许可以将就往下看,但缺少注释难免不易理解。这时候就需要下载源码了,功能强大的IDE在你查看.class文件时,就提供了源码下载功能,如下图所示:
也可以使用maven来下载对应jar包的源码,这里查看maven的教程即可,笔者不在赘述。
优秀的源码一般都有注释,通过注释便可以了解类、方法以及变量在程序中的过程。比如上图所示的方法,就是校验当前容器中的beanFactory是否为active状态,如果不是就会抛出IllegalStateException。
通过源码的注释可以更准确的理解源码。
静态,代码结构图
类图有助于理解代码的框架结构,借助工具查看接口ApplicationgContext代码层级结构:
Application接口的父类:
Application接口的实现类:
可以看到,我们在main函数中使用到的ClassPathXmlApplicationContext就是Application的一个实现类,其同级目录下还有一个FileSystemXmlApplicationContext,两个类都是通过XML文件来加载ApplicationContext,只不过一个是通过文件系统,一个通过类路径而已。
由此可见通过对代码层级结构的剖析,可以更加全面的解析spring。建议动手画一画类图效果更佳。
动态,代码调试
通过IDE的调试功能,可以跟踪代码的运行过程:
现在我要对getBean方法进行调试,看看容器是如何获得该bean。
可以看到getBean方法的具体实现在抽象类AbstractApplicationContext中
这里调用了方法assertBeanFactoryActive(),顾名思义,是校验下beanFactory是否为active状态,如果要看它的具体实现(见源码阅读部分),就继续Step into,如果这个方法是实现不是当前的首要任务,就可以执行Step over(如果调试的步骤有什么不理解的朋友,就自行百度下如何在idea下进行调试哦~)。
本文旨在阐明源码阅读的方法,就不在赘述大篇幅的源码细节。
通过这个过程读者便可以顺藤摸瓜,逐步掌握框架细节的实现。
本文到这里也就要结束了,总结下:
一是源码阅读的环境搭建,通过搭建spring Application方法来阅读源码,免除下载构建等烦恼
二是介绍了三种不错的源码阅读方法:
1、通过工具下载jar包的源码,通过注释更准确地把握类、方法以及变量的作用
2、通过静态分析,更清晰地掌握整体结构
3、通过动态运行,顺藤摸瓜,更容易地把握细节实现
本文到此就结束,希望能够帮到大家。
纯属原创,转载请声明出处。
——作者:陈来件(QQ:810522442)