为了阅读分析Spring 5源代码,需要搭建环境将源代码导入到本地。我们使用IntelliJ IDEA作为IDE工具来分析源码。网上有很多教程要么太老,要么没有经过实践验证,要么不完美报一堆错误。 本文以比较新的Spring 5.x为例,详细进行说明,而且build编译结果完美无错误。

1、环境准备

环境

版本

备注

Java

1.8.0_241

Java HotSpot™ 64-Bit Server VM (build 25.241-b07, mixed mode)

IDE

IntelliJ IDEA 2020.1 旗舰版

Git

2.27.0(已本地独立安装)

需要通过Git远程获取代码。本地独立安装了Git,在Idea中设置Git安装的路径

Gradle

IntelliJ IDEA 自带

因为Spring的源代码使用Gradle管理和构建,因此需要此插件

AspectJ

1.9.5

需要单独下载安装(下载安装的过程见文后)

以上设置(及其他IDEA的设置)具体过程截图可以参考此链接:IntelliJ IDEA 2020 安装后常规配置

2、获取源代码地址

访问https://github.com/, 在搜索框中输入spring-framework。如下图

spring源码系列教程 spring5源码_Gradle

在spring-framework工程中,如下图,右侧获得源代码的git clone的URL地址,拷贝该地址。 该URL为:https://github.com/spring-projects/spring-framework.git

注意:如果Download Zip需要注意左侧的Branch分支,以下载对应的版本。 如果不下载zip,而是直接拷贝URL地址,通过git clone则默认自动下载master主分支。

spring源码系列教程 spring5源码_Gradle_02

3、源代码导入IDEA

1、打开IDEA如下图(如果之前已经开了其他工程,则应先通过菜单File→Close Project关闭其他工程),选择“Get from Version Control” 。

然后Version control工具选择Git,在URL地址中粘贴刚才拷贝的URL地址。

spring源码系列教程 spring5源码_Java_03

2、点击“Clone”按钮,IDEA开始执行git clone,需要漫长的等待(根据网速,约一两个小时),如下图。

spring源码系列教程 spring5源码_Gradle_04

如果网络不好而报错(cloning下载过程中经常报RPC failed; curl 18 transfer closed with outstanding read data remaining the remote end hung up unexpectedly early EOF index-pack failed),则可以反复尝试几次。 根据经验尝试3~5次基本能成功,所以我一般使用这个方法。
另外:(网上提供的方法)如果在Idea配置中指向了本地单独安装的Git软件,则可以在本地单独安装的Git软件中执行:git config --global http.postBuffer 524288000 增加postBuffer大小,然后重启IDEA,据说可以避免上述问题(实际测试,设置后依然包上面的错误。)。

3、Git clone下载完毕后,会自动使用Gradle进行Build(Gradle会自动下载依赖的包,通常又得等个把小时)。最后的结果如下图。BUILD SUCCESSFULL。

spring源码系列教程 spring5源码_spring_05


4、确认源代码版本,打开gradle.properties文件,可以查看当前Sring源代码的版本。

spring源码系列教程 spring5源码_Gradle_06

4、解决错误

上面使用Gradle的build成功并不会将java源代码编译为class文件。
需要通过IDEA菜单“Build → ReBuild Project”编译才能将整个工程编译为class。 但在编译过程中会报错,报错解决过程如下:

4.1 缺少cglib和objenesis等的编译错误

为了避免与第三方class冲突,Spring把最新的cglib和objenesis给重新打包(repack)了,它并没有在源代码里提供这部分代码。需要把相关的jar获得,才能编译spring-core。 不然会报缺相关的类。

**解决办法:**在IDEA界面的最右侧找到Gradle窗口,然后在Tasks→other下面分别双击cglibRepackJarobjenesisRepackJar

spring源码系列教程 spring5源码_Gradle_07


然后会自动下载相关Jar。

**同样类似的:**还可能报java: 程序包org.springframework.oxm.jaxb.test不存在,则在Gradle窗口中,Tasks→other下面双击genJaxb

下载后在spring-core的lib目录下的jar文件,如下图:

spring源码系列教程 spring5源码_Gradle_08

4.2 Kotlin的JVM版本不对

如果报Kotlin: Calls to static methods in Java interfaces are prohibited in JVM target 1.6. Recompile with '-jvm-target 1.8',则在Settings → Build, Exexution, Deployment → Compiler → Kotlin Compiler中,修改Target JVM Version。

spring源码系列教程 spring5源码_Gradle_09

4.3 AspectJ问题

如果报一下图中错误,因为aspect不是Java标准的关键字,需要使用Ajc。

spring源码系列教程 spring5源码_spring_10


解决办法:

①先从官网https://www.eclipse.org/aspectj/downloads.php 下载文档版本的jar。

spring源码系列教程 spring5源码_Gradle_11


②然后执行“ java -jar aspectj-1.9.5.jar”,进入如下安装界面

spring源码系列教程 spring5源码_Gradle_12


③如下界面,确认当前已经存在的Java JRE的路径(通常不用修改)

spring源码系列教程 spring5源码_spring_13


④如下图,选择AspectJ的安装目标目录(根据实际情况设置)。然后点Install 安装。

spring源码系列教程 spring5源码_spring源码系列教程_14


⑤然后在IDEA中,Settings → Build, Exexution, Deployment → Compiler → Java Compiler 如下图设置。将Use compiler设置为Ajc,将Path to Ajc compiler设置为AspectJ安装目录下的lib文件夹中的aspectjtools.jar文件,同时,需要勾选Delegate to Javac选项(它能够只编译AspectJ的Facets项目,而其他普通项目还是交由Javac来编译)。

spring源码系列教程 spring5源码_spring源码系列教程_15


⑥分别对spring.spring-aop.mainspring.spring-aspects.main添加Facets属性。在IDEA中“Project Structure…”界面中,选择Facets,点击“+”号,选择AspectJ,再选spring-aop.main。 添加后自动切换到Modules界面,确认结果。

spring源码系列教程 spring5源码_spring源码系列教程_16


同样,对于spring.spring-aspects.main也按以上步骤添加Facets。 两个都添加完毕后结果如下图

spring源码系列教程 spring5源码_spring_17

5、完美编译无错误

经过以上步骤,再次通过IDEA菜单“Build → ReBuild Project”编译整个工程(两三分钟),在Messages界面中提示:Build completed successfully,没有错误(只是有警告)。

至此编译完毕

spring源码系列教程 spring5源码_Gradle_18


而且,查看每个module的build文件下,已经生成了许多class文件。如下图。

spring源码系列教程 spring5源码_spring源码系列教程_19