1.获取spring-framework源码。
推荐使用clone的方式将源码拉取到本地。
git clone https://github.com/spring-projects/spring-framework.git
git checkout origin/5.1.x
可以利用IDEA直接比较版本间的差异。在目标文件中,右键→Git→Compare with Branch...→Select Branch to Compare,这样可以对比两个版本代码的差异。
2.下载源码推荐的Gradle版本。
在Spring源码根目录/gradle/wrapper/gradle-wrapper.properties下,可以看到spring推荐gradle版本是4.10.3
下载地址:https://gradle.org/releases/
修改gradle-wrapper.properties,防止在编译时重复下载gradle包
#distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.3-all.zip distributionUrl=gradle-4.10.3-all.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME
3.配置gradle环境变量。
解压gradle包,
在系统环境变量中添加变量名:GRADLE_HOME 变量值:gradle解压后的路径...\gradle-4.10.3
在PATH后追加%GRADLE_HOME%\bin
打开cmd
4.为安装好的Gradle配置国内镜像
进入gradle安装目录,在init.d目录下新建一个init.gradle文件,并添加以下内容:
allprojects{
repositories {
def REPOSITORY_URL = 'http://maven.aliyun.com/nexus/content/groups/public/'
all { ArtifactRepository repo ->
def url = repo.url.toString()
if ((repo instanceof MavenArtifactRepository) && (url.startsWith('https://repo1.maven.org/maven2') || url.startsWith('https://jcenter.bintray.com'))) {
project.logger.lifecycle 'Repository ${repo.url} replaced by $REPOSITORY_URL .'
remove repo
}
}
maven {
url REPOSITORY_URL
}
}
}
5.修改gradle.properties
在Spring源码根目录/gradle.properties
version=5.1.12.BUILD-SNAPSHOT ## 设置此参数主要是编译下载包会占用大量的内存,可能会内存溢出 org.gradle.jvmargs=-Xmx2048M ## 开启 Gradle 缓存 org.gradle.caching=true ## 开启并行编译 org.gradle.parallel=true ## 启用新的孵化模式 org.gradle.configureondemand=true ## 开启守护进程 通过开启守护进程,下一次构建的时候,将会连接这个守护进程进行构建,而不是重新fork一个gradle构建进程 org.gradle.daemon=true
6.build.gradle 添加 阿里云 maven 仓库镜像
在Spring源码根目录/build.gradle
buildscript { repositories { maven { url 'https://maven.aliyun.com/repository/gradle-plugin' } maven { url 'https://maven.aliyun.com/repository/spring-plugin'} maven { url "https://maven.aliyun.com/repository/public" } maven { url "https://maven.aliyun.com/repository/central" } maven { url "https://repo.spring.io/plugins-release" } }
repositories { maven { url "https://maven.aliyun.com/repository/apache-snapshots" } maven { url "https://maven.aliyun.com/repository/spring" } maven { url "https://maven.aliyun.com/repository/google" } maven { url 'https://maven.aliyun.com/repository/central'} maven { url "https://maven.aliyun.com/repository/public" } maven { url "https://repo.spring.io/libs-release" } mavenLocal() }
7.IDEA通过Import Project导入spring源码
导入过程中,IDEA会识别出是gradle项目,选择gradle就可以。
8.设置IDEA中的gradle
如下设置即可
9.Reimport All Gradle Projects
进行了上述配置,这步会很顺利。
在IDEA的右侧栏会出现与项目模块相应的Gradle视图
10.编译工程
编译顺序:spring-core>>>spring-oxm>>>spring-context>>>spring-beans>>>spring-aspects>>>spring-aop
以spring-core为例,编译步骤:
1.将源码的spring-core模块下的build文件夹手动删除,或者执行gradle的spring-core/Tasks/build/clean,
2.执行gradle的spring-core/Tasks/other/compileTestJava
11.添加自己的测试调试模块
在spring项目中New Module,
运行测试项目报错:找不到InstrumentationSavingAgent。
在spring-context.gradle修改optional(project(":spring-instrument"))为compile(project(":spring-instrument")),然后重新编译一下spring-context(compileTestJava+build)
12.源码查看技巧
读源码的好处:提高培养代码架构思维、深入理解框架
原则:
定焦原则:抓主线→以问题为主线,带着问题看源码
宏观原则:站在上帝视角,关注源码结构和业务流程(淡化具体某行代码的编写细节)
读源码的方法和技巧
断点(观察调用栈)→使用Hello World级别的测试用例,打断点,看调用栈,定位重点方法分析;看变量、参数
反调(Find Usages)
经验(spring框架中的doXXX,做具体处理的地方)
搭建源码环境→看架构图→断点看执行顺序