为了阅读分析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-framework工程中,如下图,右侧获得源代码的git clone的URL地址,拷贝该地址。 该URL为:https://github.com/spring-projects/spring-framework.git
注意:如果Download Zip需要注意左侧的Branch分支,以下载对应的版本。 如果不下载zip,而是直接拷贝URL地址,通过git clone则默认自动下载master主分支。
3、源代码导入IDEA
1、打开IDEA如下图(如果之前已经开了其他工程,则应先通过菜单File→Close Project关闭其他工程),选择“Get from Version Control” 。
然后Version control工具选择Git,在URL地址中粘贴刚才拷贝的URL地址。
2、点击“Clone”按钮,IDEA开始执行git clone,需要漫长的等待(根据网速,约一两个小时),如下图。
如果网络不好而报错(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。
4、确认源代码版本,打开gradle.properties文件,可以查看当前Sring源代码的版本。
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下面分别双击cglibRepackJar
和objenesisRepackJar
然后会自动下载相关Jar。
**同样类似的:**还可能报java: 程序包org.springframework.oxm.jaxb.test不存在
,则在Gradle窗口中,Tasks→other下面双击genJaxb
下载后在spring-core的lib目录下的jar文件,如下图:
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。
4.3 AspectJ问题
如果报一下图中错误,因为aspect不是Java标准的关键字,需要使用Ajc。
解决办法:
①先从官网https://www.eclipse.org/aspectj/downloads.php 下载文档版本的jar。
②然后执行“ java -jar aspectj-1.9.5.jar”,进入如下安装界面
③如下界面,确认当前已经存在的Java JRE的路径(通常不用修改)
④如下图,选择AspectJ的安装目标目录(根据实际情况设置)。然后点Install 安装。
⑤然后在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.spring-aop.main
和spring.spring-aspects.main
添加Facets属性。在IDEA中“Project Structure…”界面中,选择Facets,点击“+”号,选择AspectJ,再选spring-aop.main
。 添加后自动切换到Modules界面,确认结果。
同样,对于spring.spring-aspects.main
也按以上步骤添加Facets。 两个都添加完毕后结果如下图
5、完美编译无错误
经过以上步骤,再次通过IDEA菜单“Build → ReBuild Project”编译整个工程(两三分钟),在Messages界面中提示:Build completed successfully,没有错误(只是有警告)。
至此编译完毕
而且,查看每个module的build文件下,已经生成了许多class文件。如下图。