第1章 准备源代码环境

半亩方塘一鉴开,天光云影共徘徊。

问渠哪得清如许,为有源头活水来。

—【宋】朱熹 《观书有感》

1.1 安装JDK

在开发Spring应用和分析Spring源代码之前,需要做一些准备工作,其中搭建Java环境是必不可少的。Spring 3.0要求Java 5以上版本,JDK需要1.5或1.5以上版本。如果JDK的版本低于1.5,则可进入网站http://Java.sun.com/javase/downloads下载最新的JDK安装程序。

提示 安装完后,要检查JDK是否配置正确。某些第三方的程序会把自己的JDK路径加到系统PATH环境变量中。这样,即便安装最新版本的JDK,系统还是会使用第三方程序所带的旧版本JDK。这种情况下,Java环境可能无法正常运行,手工修改系统PATH路径可以解决这个问题,比如重新设置PATH路径指向新JDK的安装路径。

1.2 安装Eclipse

运行Spring只需要JDK,但是一个好的开发环境和源代码阅读环境可以事半功倍。Eclipse是最流行的Java集成开发环境之一,Eclipse的JDT提供了良好的代码分析功能,它们是我们在分析Spring的实现原理过程中会用到的基本工具。比如,可以用Eclipse分析Java类和接口的继承关系、查看Java方法的调用关系、搜索代码等。

在Eclipse中分析Java类和接口的继承关系的具体做法如下:在代码区中选择需要的类和接口定义,然后使用右键选取Open Type Hierarchy或按快捷键【F4】,可以在Hierarchy View中看到继承关系,如图1-1所示。

在Eclipse中分析Java方法的调用关系的具体做法如下:在代码区中选择相应的方法定义,然后用右键选取Open Call Hierarchy或者按下快捷键【CTRL+ALT+H】,可以在Call Hierarchy视图中看到方法的调用关系,提供了逐层的方法调用追溯的功能,对查找方法的相互调用关系非常有用,如图1-2所示。

在Eclipse中使用搜索功能,使用菜单上的Search可以打开搜索对话框,搜索结果在Search View中显示。如果双击Search View中的搜索结果列表中的某一项,就可以直接打开该搜索结果对应的出处,具体如图1-3所示。

图1-1 在Eclipse中查看类的继承关系

图1-2 在Eclipse中参看方法调用关系

图1-3 在Eclipse中使用搜索功能

1.3 安装辅助工具

作为集成的IDE环境,Eclipse为许多相关的插件提供了应用平台。例如,SVN的Eclipse插件为开发者提供了很好的源代码管理功能,Spring的Eclipse IDE插件为开发Spring应用提供了很好的帮助。对应的插件在Eclipse中安装以后,这些功能就可以直接在Eclipse IDE环境中使用;通常这些插件是作为Eclipse的一个View或者一个Perspective出现在集成IDE环境中的。下面我们来看看这些插件在Eclipse中的安装。我们先对在Eclipse中安装SVN插件做一个简要的说明,关于Spring Eclipse IDE的安装和简要使用,将在第8章中详细介绍。

关于源代码管理工具的具体使用,本书就不做详细的说明了,记得早在10几年前我使用的版本管理工具是CVS。当时是在一台SUN Ultra60工作站上与版本管理工具CVS有了第一次亲密接触。它有一个简单的图形界面,非常直观,使用起来也很方便,从那时候起,我才开始有了源代码管理的基本概念。后来发现,这些概念在其他工具上也是同样适用的,例如版本、分支、基线、合并、比较等。

慢慢更深入地接触了软件产品开发以后,知道这些操作都是在进行软件配置管理计划时需要定义的基本过程,这些基本过程保证了软件产品在协同开发和构建过程中的一致性,成为软件开发中不可缺少的变更管理的重要组成部分。无论是使用CVS、SVN还是ClearCase,是使用命令行方式还是图形界面的方式,基本的概念都需要深刻的理解和掌握。ClearCase在大型商业软件开发领域被普遍使用,而CVS和SVN却是开源领域和中小型企业应用开发领域的主角。

值得注意的是,CVS和SVN本身也是开源软件,提供的功能已经足以满足开源软件开发的需求。这里有个有趣的问题就是,不知道CVS和SVN本身的开发项目是不是用自己做的代码管理?感兴趣的读者不妨去做个调研来告诉大家。如果读者对开源软件的源代码管理感兴趣,可以阅读Open Source Development with CVS(作者Karl Fogel和Moshe Bar)这本书,书中详细介绍了如何使用CVS对开源软件的源代码进行管理。

Eclipse中自带的源代码管理客户端就是CVS的客户端,Eclipse使用者可以直接使用。此外,这个CVS客户端因为有Eclipse的各种视图的支持,所以使用起来也是非常的方便。但是,由于Spring 3.0的源代码是用Subversion来进行管理的,而在Eclipse的默认安装中是不带SVN客户端这个插件的,所以这里有必要对SVN客户端的安装和使用做简要的介绍。这些源代码管理工具是开源软件开发中常用的,所以掌握这些工具的基本使用对我们理解开源软件的开发方式有很大的帮助。我们在这里使用的是一个开源的SVN客户端—Subclipse,一个在Eclipse IDE中使用的SVN插件。其官方网站是http://subclipse.tigris.org,其下载页面如图1-4所示。

图1-4 SVN客户端下载

在Eclipse的Help菜单下选择Software Updates,如图1-5所示。

打开Software Updates and Add-ons对话框,选择Available Software面板,可以看到在我们的Eclipse IDE环境中已经安装的插件,如图1-6所示。

单击Add Site…按钮打开Add Site对话框。具体的Eclipse更新地址可以在http://subclipse. tigris.org/单击Download and Install页面找到,我们在Location中输入插件更新地址,结果如图1-7所示。

图1-5 在Eclipse中安装插件

图1-6 在Eclipse中安装插件

图1-7 在Eclipse中安装插件

单击OK按钮关闭Add Site对话框。Eclipse获取到插件列表,更新Software Updates and Add-ons对话框的内容,并选择Subdipse update sites,如图1-8所示。

图1-8 在Eclipse中安装插件

勾选Subclipse插件及其子项,单击Next按钮,如图1-9所示。

图1-9 在Eclipse中安装插件

单击Install按钮,显示Progress Information进度对话框开始下载安装包,下载完成后的界面如图1-10所示。

图1-10 在Eclipse中安装插件

插件安装完成,重新启动Eclipse, SVN Eclipse插件安装完成,如图1-11所示。

图1-11 在Eclipse中安装插件

这时可以看到在Eclipse中SVN的相关视图,如图1-12所示。

图1-12 Eclipse中安装好的SVN视图

如果你不喜欢在Eclipse中使用SVN客户端,还可以直接下载SVN的独立客户端进行使用,比如TortoiseSVN(一只可爱的小海龟),这也是一个开源的源代码管理工具,可以在http://tortoisesvn.tigris.org/下载,如图1-13所示。

图1-13 下载SVN独立客户端TortoiseSVN

下载安装完成后,如果打开Windows的文件管理器,点击右键,可以看到SVN的菜单选项已经在操作列表里出现了,由于集成在Windows的文件管理器中,这个小海龟使用起来也是非常方便的。如图1-14所示,可以看到小海龟的SVN操作选项列表。比如checkout和创建代码库等等。从这里看到的SVN的基本功能,和我们在Eclipse中使用的SVN客户端的基本功能是类似的,但在这里的TortoiseSVN做为独立的SVN客户端,是脱离Eclipse而独立使用的,所以在Eclipse中浏览代码的时候需要注意对代码的更新和同步。

图1-14 SVN客户端在Windows系统中的使用

1.4 获取Spring源代码

有了SVN客户端的支持后,我们可以到Spring的官方网站上获取Spring 3.0的源代码。在Spring 3.0之前的源代码版本中,是在sourceforge以CVS repository的形式提供下载的。但是,根据当前Spring官方网站的信息,Spring 3.0版本的源代码改为使用SVN方式进行源代码管理。进入Spring官方网站http://www.springsource.org/,打开Project,然后选择Spring(如图1-15所示),可以看到关于Spring源代码库的描述,我们使用的代码库位置在Spring官方网站上可以找到,即https://src.springframework.org/svn/spring-framework/。

图1-15 Spring官方网站

确定了Spring源代码的下载位置后,我们开始使用Eclipse SVN客户端进行源代码下载,具体过程是:在Eclipse→Windows→Open Perspective→Others,打开SVN Perspective,如图1-16所示。

图1-16 下载Spring源代码

单击添加SVN资源库,添加Spring源代码下载的代码位置,单击Finish,如图1-17所示。

图1-17 下载Spring源代码

这时在SVN资源库视图中可以看到详细的Spring源代码的代码库结构,因为是开源项目,Spring的代码库对所有人开放check out权限。但是,如果要check in代码,则需要相应的SVN权限作为developer才可以,用右键点击trunk,检出代码,单击Finish,如图1-18所示。

图1-18 下载Spring源代码

这时会经历较长时间的代码检出过程,这个过程把Spring代码从服务器检出到Eclipse的本地工作环境。代码检出完毕后,可以把Eclipse切换到Java Perspective,这时已经可以在Packet Explorer中看到与Spring代码库同步的代码了,如图1-19所示:

这时就可以像在你自己的项目里使用Eclipse浏览代码那样来浏览Spring的源代码了,整个Spring的源代码已经在我们面前毫无保留、一览无遗地呈现了。

图1-19 下载Spring源代码

1.5 Spring源代码的组织结构

我们已经把Spring的源代码检出到了本地,整个代码的结构如图1-20所示,我们对它的目录结构做一些简要的说明,以方便大家对源代码进行浏览。

图1-20 Spring源代码结构

Build-spring-framework是整个Spring源代码的构建目录,里面是项目的构建脚本,如果要自己动手构建Spring,可以进入这个目录使用ANT进行构建。其他的目录从名字上就可以很容易地看出来是Spring的各个组成部分,比如,org.springframework.context是IoC容器的源代码目录,org.springframework.aop是AOP实现的源代码目录,org.springframework.jdbc是JDBC的源代码部分,org.springframework.orm是O/R Mapping对应的源代码实现部分,org.springframework.samples.petclinic是Spring提供的一个应用示例的源代码,便于我们开发Spring应用时参考。

Spring源代码中的每个包(比如org.springframework.context)都以一个相对独立的子项目存在于代码库中。之所以说这些包是子项目,是因为每个包都可以作为独立的项目导入到Eclipse中,都有Eclipse的项目配置文件,有针对这些包的代码的测试用例,这些测试用例组织在src/test目录中。另外还有针对自己包的build构建文件,这些构建文件同时也是构成整个Spring项目构建的一部分。这种代码组织结构使得包之间的相互耦合相对较小,非常有利于各个子模块的并行开发、集成与测试。在每个源代码包中,都有着类似的代码结构划分,比如src是源代码目录,其中的main目录用来存放产品代码,test用来存放测试代码。main里面的java目录用来存放java源文件,而resources目录用来存放资源文件。target目录用来存放编译好的classes文件,这个target名字让我想起了在嵌入式软件的开发系统中也常看到这样的目录,在那些系统里,这些目录常用来存放目标代码,往往还可以针对不同的处理器结构和平台(比如X86平台、PPC平台、ARM平台等)。在这里,因为Java的跨平台特性,所以只要一个target即可,也许这些名字也是Java起源于嵌入式系统开发的佐证之一吧。这些代码的组织规划很统一,让整个Spring的源代码看起来非常整齐,浏览起来非常方便。图1-21以org.springframework.context包为例,大家可以体会一下。

图1-21 Spring源代码包的内部结构

下面看看整个Spring的代码库结构。在整个代码库中,我们前面check out的是trunk上的代码,也就是当前Spring最新的提交代码,相当于CVS中的HEAD版本。如果要获取Spring 3.0的某个基线版本的代码,可以在tags目录中看到,然后check out到本地即可,这个过程和check out在trunk上的代码是一样的。在使用SVN和CVS做代码管理的时候,它的基本思路也和我们使用ClearCase的时候不太一样,在ClearCase里,如果要检出代码,一般需要先拉一个分支,然后再做check out,这样对并行开发没有影响,同时使用ClearCase的时候往往需要对各种分支的权限做比较详细的规划;但在CVS和SVN中,管理过程有很大的不同,往往代码的检出和提交是比较自由的,但是对基线版本的构建却是比较严格的,所以在这里不太能够看到分支的使用;这也是由开源软件的开发特点决定的。让我们回到前面的目录结构,在tags目录下,我们可以看到现在已经开发好的基线版本,比如Spring3.0 M1/M2/M3等,这些都是一些重要的开发里程碑,熟悉软件配置管理的读者看到这里一定会发出会心的一笑,感觉又回到了我们在日常产品代码开发中熟悉的配置环境中来了。如果你觉得基线版本的代码更新太慢,而你又急切地想了解代码的最新改动,可以直接参看trunk的代码,这绝对是Spring开发团队最新出炉的作品。从这点上看,互联网真的是把整个世界都变平了。另外一点值得注意的是,从现在的代码组织结构上可以看到,这个代码仓库是从Spring 3.0开始为Spring服务的,因而无法在这里找到Spring 3.0版本以前的Spring源代码。如果需要获取之前版本的源代码,需要找到以前代码库的具体位置,这些信息可以到Spring的官方网站上获取。现在我们看到的代码库的快照如图1-22所示。

图1-22 Spring源代码库的结构

这就是我们看到的Spring源代码!经过这么多年的发展,其核心已经比较稳定了,包括各个基本包的设计和命名。同时,我们从这些源代码的组织也隐约地看到了Spring的配置管理和构建过程,比如项目组织、测试管理、构建工具以及依赖关系管理工具的使用等,这些都为Spring代码的高质量开发奠定了一个良好的工程环境。有兴趣的读者不妨自己做个研究,看看Spring的构建过程是怎样完成的。

1.6小结

问渠哪得清如许,为有源头活水来。本章我们从Spring的源头开始,对Spring源代码的工程环境进行了介绍,通过这些介绍,读者已经具备自己动手对源代码进行分析的能力。另外,我们使用Eclipse开发环境,对源代码进行分析的一些实践经验,以及和开源软件开发过程紧密相关的一些基本知识进行介绍,这些知识不仅对Spring适用,而且对其他的开源软件开发也具有非常好的借鉴意义。

有了软件工程环境的有力支持,以及在这个环境基础上,对Spring源代码结构的基本了解,我们已经具备了阅读Spring源代码的基本条件,就是这些源代码,是我们深入了解Spring实现原理的有力武器,也是开源软件最宝贵的财富。让我们养成动手到源代码中去看个究竟以解迷惑的习惯吧,从个人的切身体验来看,这可是一个深入了解软件实现原理的好习惯。对实现的商业软件产品也是一样如此。让我们瞭望一下这片生机勃勃而又有些神秘的代码丛林,就像探险者面对茂密的热带雨林那样,一起做个深呼吸,准备开始这充满乐趣和挑战的Spring源代码之旅吧!