前言
学习Spring源码的重要前提,则是需要去编译源码到本地环境,这样则是方便我们在本地环境添加注释、断点调试、查看类图等,不过相信很多小伙伴在编译Spring源码的过程中相继遇到了很多困难而导致放弃学习,而本文就是来阐述如何正确编译Spring的源码,最好网速一定要好,否则编译源码会让小伙伴们体验极差。
Spring源码编译环境
环境及版本介绍
JDK环境:1.8及以上
Spring版本:作者在写本文的时候是用的5.2.10.RELEASE版本,但是现在Spring官网release版本已经到了5.2.12了
开发工具:IntelliJ IDEA 2019.3
编译工具:Gradle-5.6.4-bin
操作系统:windows 10
前置准备
1.安装并配置JDK环境
这里笔者就不演示配置了,百度有很多,小伙伴们可自行百度哈
2.下载和配置Gradle编译工具
访问Gradle
https://services.gradle.org/distributions/
![](https://i-blog.csdnimg.cn/blog_migrate/4be5c504e4acfe9dcbde7909df148996.png)
注意:不建议下载比较新的gradle版本,可能使用时会有各种冲突,我选择的是下载gradle-5.6.4-bin源码包
下载并解压压缩包
![](https://i-blog.csdnimg.cn/blog_migrate/766759df5b77481a21ccc8050e53e438.png)
配置Gradle环境变量
新建变量
变量名:GRADLE_HOME
变量值:解压到的目录
![](https://i-blog.csdnimg.cn/blog_migrate/fddbb81b20cca4352ffb007af169e1bf.png)
新建变量
变量名:GRADLE_USER_HOME
变量值:自定义Gradle仓库目录或者Maven的仓库目录
![](https://i-blog.csdnimg.cn/blog_migrate/3e742513c8d11ad4c3a35fa7a8e21c7c.png)
新建变量
变量名:Path
变量值:%GRADLE_HOME%\bin;
![](https://i-blog.csdnimg.cn/blog_migrate/dbecd8b271a0df44d700f3b560a35b11.png)
验证Gradle是否安装成功
在命令行工具里面,输入 gradle -v,如下图则代表安装成功
![](https://i-blog.csdnimg.cn/blog_migrate/9a67cd11ac395ee7422d752a87c24dbb.png)
3.下载Spring源码
1.访问Spirng官方
https://spring.io/
2.下图有很多Spring开源的项目,我们选择Spring FrameWork即可
![](https://i-blog.csdnimg.cn/blog_migrate/69206c41072536362ca2f45dc6297801.png)
3.我们点击Github头像,跳转到github中
![](https://i-blog.csdnimg.cn/blog_migrate/a6648deec0553eb39de16ac5df2b9981.png)
4.我们下载relese分支即可,不要下载其他的分支,其他分支是不稳定的
![](https://i-blog.csdnimg.cn/blog_migrate/62a98904ec31ce19efb2cb83d655a424.png)
5.这里多种下载方式,我这里选择直接下载压缩包,小伙伴自己喜欢什么方式下载,选择什么方式即可
![](https://i-blog.csdnimg.cn/blog_migrate/f7b91082bedb4afe7b28afa592f35be3.png)
6.我这里选择直接下载压缩包啦 ,然后解压
![](https://i-blog.csdnimg.cn/blog_migrate/0c1a4c5bd11955fe89332afd5aecafbf.png)
到此我们Spring源码就已经下载完成了,接下来开始编译源码啦
编译Spring环境
进入Spring源目录
![](https://i-blog.csdnimg.cn/blog_migrate/44481c9654ef74eb06750e3dd0852286.png)
看到上图我所指向的地方,该地方gradlew.bat就是等下我们需要运行的命令;但是先不着急运行;因为这个命令会去读取一个文件;在这个文件当中配置了gradle的版本和下载地址;一旦运行变化自动下载,有时候会下载不过来,而且有时候可能需要翻墙等等,就算下载过来了目录在哪里也是他自动指定的,下载过来后解压目录等等都是在那个文件里面配置,索性我们自己下载过来然后修改这个配置文件;
我们从根目录进入 gradle/wrapper 文件夹,修改gradle-wrapper.properties
文件
Spring程序是通过grale进行编译的,我们现在有两种选择方式
1.我们本地无需下载Gradle,在下面这个配置里面,通过远程gradle下载编译
2.我们本地下载Gradle,下载目录等地址我们都可以自定义(我这里用的是本地下载gradle的工具进行编译)
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
#distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip
distributionUrl=file:///d:/software/gradle-5.6.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionBase 下载之后的目录(从distributionUrl下载过来是一个zip文件,存放的目录)
distributionPath 会自动拼接 distributionBase
zipStoreBase 是解压目录
改完这个配置也不要急着运行命令编译,因为当自动下载完gradle之后会通过gradle去编译spring源码,这里就涉及到一个gradle的中央仓库的问题了,编译过程中会下载大量的依赖,如果你采用默认的依赖那么这个编译过程一定特别漫长,而且会失败,于是我们需要修改中央仓库为国内的阿里云,这样就会快很多,如何修改呢?
返回根目录,找到 build.gradle文件,打开并且编辑添加阿里云的仓库
![](https://i-blog.csdnimg.cn/blog_migrate/ada9a9745c33184bc989cbc38b81cb3c.png)
![](https://i-blog.csdnimg.cn/blog_migrate/9763dd6fd46e5cf13588cd3d20ccb527.png)
repositories {
maven{ url 'https://maven.aliyun.com/nexus/content/groups/public/'}
maven{ url 'https://maven.aliyun.com/nexus/content/repositories/jcenter'}
mavenCentral()
maven { url "https://repo.spring.io/libs-spring-framework-build" }
}
至此万事具备只欠东风了,cmd到项目根目录运行 gradlew.bat
这个过程会相当漫长取决于你的网速,因为我之前已经编译过了,中间缓慢的过程笔者无法展示出来,不过小伙伴需要耐心等待
可能最后结果会失败,如果显示失败就再运行一遍gradlew.bat直到他编译成功;下图是显示编译成功的结果
![](https://i-blog.csdnimg.cn/blog_migrate/bde3e2ffd594cc69b6caa7b1fca2c0a7.png)
执行指令预编译spring源码(可能需要耗时几十分钟,看网速)
然后再打开源码所在文件夹,在windows cmd命令中输入
gradlew :spring-oxm:compileTestJava
![](https://i-blog.csdnimg.cn/blog_migrate/55b6fd227a28c098d8727ae355488bc8.png)
如上图就编译完成了,可以开始愉快的Spring源码之旅了
我们导入项目之前,先任意打开一个你之前的项目,先对IDEA的Gradle进行全局设置一下哦
我们看到如下图操作
Gradle user Home:因为我spring编译使用的是本地gradle,所以这里选择本地gradle仓库
User Gradle from: 我们选择Specified location,然后在后面我们选择自己的解压后的gradle目录(如果不选择,默认使用idea的gradle,又会重复下载jar,所以记得设置自己的gradle)
![](https://i-blog.csdnimg.cn/blog_migrate/4cd7e25aeafea0102ac52fcefab44b5f.png)
设置完成后,我们就着手准备导入Spring源码项目啦
![](https://i-blog.csdnimg.cn/blog_migrate/4922c1bcd527a174ef5871016baed86b.png)
然后选择根目录中的build.gradle文件进行导入
![](https://i-blog.csdnimg.cn/blog_migrate/0e2e1d555cc807f429a962661682e6db.png)
我这里大概等了10分钟左右就初始化完了
![](https://i-blog.csdnimg.cn/blog_migrate/9d7487b7249a0d151b8cca9892961638.png)
初始化完成之后,最好在点击一下刷新按钮,防止网络波动原因,导致前面初始化操作,可能jar下的不完整
![](https://i-blog.csdnimg.cn/blog_migrate/c03daf1d5307788b190c999f13221cf9.png)
正确构建之后如下图
![](https://i-blog.csdnimg.cn/blog_migrate/208de475de6302be07066ad49a1bd1cd.png)
接下来要对idea进行设置,不然每次idea运行都会通过gradle去编译运行gradle运行编译特别慢,需要改成idea自己编译运行
![](https://i-blog.csdnimg.cn/blog_migrate/7f71b968d30420a873f5e4a64a784d8c.png)
再次说明一下这里不是一定要改,但是如果你不改用默认的则会启动特别慢,改成idea快的不止一点点
改完之后便可以建一个子model来测试了,但是一定得建gradle的项目,因为spring源码这个父项目就是用gradle来开发的
![](https://i-blog.csdnimg.cn/blog_migrate/fe5fb6d96586ca80d8420ec4a8d317f9.png)
![](https://i-blog.csdnimg.cn/blog_migrate/9fdc4175cf86b37c797d20d5e819dcbb.png)
![](https://i-blog.csdnimg.cn/blog_migrate/c3a31925688c8928f7223869a55bebf2.png)
![](https://i-blog.csdnimg.cn/blog_migrate/99a995f96b15164b229c57e240148e44.png)
建好项目之后再gradle的配置文件中添加spring的依赖——相当于你建了一个maven项目,在pom文件中添加spring的依赖
compile(project(":spring-context"))
![](https://i-blog.csdnimg.cn/blog_migrate/5b5b7e6180507f05e785ee43d9a912ac.png)
然后开始开始完善项目的其他类
配置类的代码
@Configuration
@ComponentScan(value = "com.dream.sunny")
public class SunnyConfig {
}
普通注入类代码
@Component
public class InstanceA {
}
@Component
public class InstanceB {
}
启动类
public class SunnyStart {
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(SunnyConfig.class);
System.out.println(annotationConfigApplicationContext.getBean(InstanceA.class));
}
}
右键运行——可能你会出现一些错误;比如笔者这里就出现了某些类找不到的错误
![](https://i-blog.csdnimg.cn/blog_migrate/fbb7286ef6ce7f51d9928fc5e7481a32.png)
如上图所示,出现的错误,小伙伴可以按照我下面的步骤去解决即可
![](https://i-blog.csdnimg.cn/blog_migrate/f2d4b4b5efc6d46964e7703a88d3bf55.png)
![](https://i-blog.csdnimg.cn/blog_migrate/d9a08c5308a9a2acca85f6a9185d74a7.png)
![](https://i-blog.csdnimg.cn/blog_migrate/923656c5ed4fd5a25bb13035b79ed2b9.png)
当再次右击运行的时候,又会出现找不到某些类的情况
![](https://i-blog.csdnimg.cn/blog_migrate/31cee18d0c20c6dc9788ccbe051d61ba.png)
遇到这种问题是因为这个类所在的项目没有编译这个类—说白了就是没有产生class文件;比如上图那个错误便是没有找到 InstrumentationSavingAgent 这个类,那么你首先找到这个类所在的项目(InstrumentationSavingAgent类所在的项目为spring-instrument);再看看out文件下面是不是有这个class;比如笔主这里连out文件夹没有—build文件下下面是gradle产生的,我们上面已经把编译方式改成了idea,idea默认编译文件为out——说白了就是这个build可以直接删除;out文件夹都没有表示这个项目当中的java类idea压根没有编译;我们可以运行这个项目下面的测试类test让idea去帮我们编译这些java类
老套路,小伙伴跟着我的步骤即可解决啦
![](https://i-blog.csdnimg.cn/blog_migrate/5a5611cee19a2805377178830246bfa3.png)
找到test文件夹下面的java文件夹右键 run all tests
![](https://i-blog.csdnimg.cn/blog_migrate/cd40ce4fad604b589912aa6a0cd3c811.png)
出现如上图的错误,小伙伴不必担心,完全可以忽略掉,因为我们运行tese包,但是包中没有一个类,但是IDEA还是会帮我们编译的,只是编译是个空的
我们仍然可以看到out文件夹产生了
好,问题解决完成后,我们再次运行我们的启动类,如下图就成功啦.
![](https://i-blog.csdnimg.cn/blog_migrate/9cc653d76c668a58f15b6f67ebd8886c.png)
至此,Spring源码如何在IntelliJ IDEA如何编译这篇文章就废话完毕了。
写这篇文章目的我希望把它作为Spring系列的开始,没有环境的学习就像你想抬一个没有边角的桌子无处施力,如果大家在编译时有什么问题欢迎指出。
由于本人精力有限,现在主要在微信公众号写文章了,如果小伙伴觉得文章写的不错的,可以关注一下我的微信公众号:黎明大大