Skip to content

Gradle 项目构建工具

Spring 源码是使用 Gradle 进行构建,需要下载与安装 Gradle。

Gradle官网:https://gradle.org/

具体 Gradle 安装详见《Gradle基础笔记》

Spring 源码编译流程

个人编译是使用 IDEA,可以直接参考源码工程中的《import-into-idea.md》文档

修改源码项目配置

  1. 进入 Spring 源码的根目录,打开 gradle/wrapper/gradle-wrapper.properties 配置文件。其中配置项说明如下:
  • distributionUrl:表示的就是 gradle 的下载地址,默认配置的是一个远程 URL。
  • distributionBase:下载后存放的目录,默认就是用户目录下的 .gradle 目录;
  • zipStoreBase:解压后存放的目录

构建的过程中发现配置的下载地址速度非常慢,因此可以先下载 gradle 的压缩包到本地,然后修改配置文件从本地获取 gradle,这样一来编译构建就会快很多了。所以将配置修改为

properties
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=file\D:/dev/spring-sample/gradle-7.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

上述配置的意思就是如果运行 gradlew 脚本会自动去 D:/dev/spring-sample/gradle-7.5-bin.zip 这个目录下载一个 gradle 到当前用户的 .gradle\wrapper\dists 目录并解压

注:windows 系统的路径写法待确认

  1. 修改源码项目的 settings.gradle 文件,增加阿里云仓库 spring 插件库
json
pluginManagement {
 repositories {
     // 阿里云仓库 spring-plugin (旧版)
        // maven { url 'https://maven.aliyun.com/repository/public' }
        // 阿里云仓库 spring-plugin (新版)
        maven { url 'https://maven.aliyun.com/repository/spring-plugin' }
  gradlePluginPortal()
  maven { url 'https://repo.spring.io/plugins-release' }
 }
}
  1. 修改源码项目的 gradle.properties 文件,修改一些参数配置
properties
version=5.3.10
#org.gradle.jvmargs=-Xmx1536M
org.gradle.jvmargs=-Xmx2048M
org.gradle.caching=true
org.gradle.parallel=true
kotlin.stdlib.default.dependency=false
  1. 修改源码项目的build.gradle文件,增加阿里云仓库
groovy
repositories {
    // 添加 maven 本地仓库
    mavenLocal()
    // 阿里云仓库地址(老版)
 // maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
 // maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter'}
    // 阿里云仓库地址(新版)
 maven { url 'https://maven.aliyun.com/repository/public' }
 maven { url 'https://maven.aliyun.com/repository/central'}
 mavenCentral()
    maven { url "https://repo.spring.io/libs-spring-framework-build" }
}

预编译项目

参考源码工程提供的导入参考文档《import-into-idea.md》,在导入 idea 之前需要进行预编译。进入 Spring 源码工程根目录,执行以下 gradle 命令对 spring-oxm 与 spring-core 这两个模块进行预编译

bash
./gradlew :spring-oxm:compileTestJava
./gradlew :spring-core:compileTestJava

Tips: 如果使用 cmd 命令行窗口,可以省略“./

编译模块,编译成功后会有“BUILD SUCCESSFUL”的提示。

导入源码

导入IDEA (File -> New -> Project from Existing Sources -> Navigate to directory -> Select build.gradle)

使用 IDEA 导入 Spring 源码,idea 默认会根据 ${spring.dir}\gradle\wrapper\gradle-wrapper.properties 文件的配置,自动下载 gradle,下载完 gradle 就会开始下载 Spring 源码依赖。若使用本机安装好的 gradle,可以直接取消这个过程。

Notes:

  1. 用 idea 打开 spring 源码工程,需要检查是否已经安装 kotlin 插件。如果安装,则需要重启 idea
  2. 需要先按上一个步骤编译工程后再导入

IDEA 的 Gradle 配置

打开【Settings】面板,选择【Build, Execution, Deployment】->【Gradle】

  • 设置【Gradle user home】,用于设置 Gradle 缓存、依赖、.gradle 压缩包的解压之后的文件等保存路径。比如设置为 D:\.gradle
  • 设置【Build and run using】和【Run tests using】
    • Gradle (Default):使用 Gradle 来构建项目和运行任务。
    • IntelliJ IDEA:选择使用 IDEA 来构建和运行项目,对于一些纯JAVA/Kotlin项目,使用这种方式可能会更快。但 IDEA 并不是支持所有 Gradle 插件,项目如果使用其中一些插件可能无法正确构建项目。

Tips: 此处如果测试使用 idea 进行编译运行没有问题,则推荐使用 idea 编译,会比使用 gradle 运行编译快。

  • 设置【Use Gradle from】,用于配置使用的 Gradle 位置,具体选项如下:
    • 'gradle-wrapper.properties' file:使用导入工程中的 gradle-wrapper.properties 文件中配置
    • 'wrapper' task in Gradle build script:使用 Gradle 构建脚本中的'wrapper'任务
    • Specified location:指定 Gradle 的安装位置

最终配置示例如下(按需修改各个配置项):

保存修改后,会自动触发 gradle 的重新编译。

如无自动触发编译,可以手动点击刷新

正常情况下,此时gradle编译将比较快,会有一个索引文件过程,但是不需要额外的下载gradle和依赖了。编译成功效果如下:

排除 spring-aspects 模块

在源码编译的过程中,可能会出现以下错误:

是因为 spring-aspects 模块编译时是依赖ajc编译器,这个 IntelliJ IDEA 没有默认安装。只要将 spring-aspects 模块排除即可。排除的步骤如下:

  1. 右键项目,选择【Load/Unload Modules...】

  1. 选择 spring-aspects 模块 unloaded

  1. 修改工程的根目录的 settings.gradle 文件,移除 spring-aspects 模块

  1. 点击刷新,重新编译。

AspectJ 编译器(非必须)

安装 AspectJ 编译器插件是为了解决使用 AOP 相关测试

下载与安装

AspectJ 官网下载 AspectJ 编译器

值得注意:官网下载页面中,只有1.9.6版本,1.9.7往后的版本都在github仓库发布

下载完成后,进入 jar 包所在目录吕,执行以下命令安装ajc编译器。

bash
java -jar aspectj-1.9.5.jar

选择jdk目录

选择安装的目录安装即可

IDEA 设置 AspectJ 编译器

  1. 打开 Idea,先安装 Aspectj 插件,并启用此插件

  1. 将 IDEA 编译器设置为 ajc,然后设置 AspectJ 安装目录下的 lib 文件夹中的 aspectjtools.jar 文件,再勾选【Delegate to Javac】选项。

  1. 点选【File】->【Project Structure】->【Modules】,将 spring-aop_main 和 spring-aspectjs_main 两个模块添加 AspectJ Facets,

  1. 把项目重新 build project,然后再成功运行 AOP 相关测试。即源码中可以使用 aspectj aop 了。

Spring 各版本的下载地址

Spring 5.3.10

此教程是基于个人 git 库的 Spring 5.3.10 源码编译的,并不是 Github 原生的 Spring 5.3.10 源码,有一些差别,但都是 gradle 配置文件的微小改动,比如把某些依赖从 optional 改成 compile 级别(主要是为了方便编译),其他都没改动。

编译使用的 IDEA 版本是 2021.1.3,用其他 IDEA 版本可能会遇到各种各样的问题。

git clone 的地址为:

Spring 5.2.8.RELEASE

注释的源码引用

方式一:直接在源码工程中创建测试代码

像 maven 工程一样,在源码工程中创建自定义的测试示例等模块,直接依赖本源码工程各个模块即可。

Tips: 此方式就很方便边看源码,边调试。但需要有 Gradle 工具的相关知识。

  1. 创建新的 Grdle 模块

  1. 设置子模块的名称

  1. 修改自定义模块的 build.gradle 配置,引入源码中核心模块的依赖
plugins {
    id 'java'
}

group 'org.springframework'
version '5.3.10'

repositories {
    mavenCentral()
}

dependencies {
    // spring 核心依赖
    // compile(project(':spring-context')) // 注意:compile 语句已弃用,并已在 Gradle 7.0 中删除。
    // 后面版本改用 implementation 或 api
    implementation project(':spring-context')

    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
}

test {
    useJUnitPlatform()
}

Notes: 如果没有引入依赖时,在 Gradle 面板中刷新一下。还就是已经使用 Gradle 7.5 版本,因此 compile 语句已经被移除,改使用 implementation 引入依赖

  1. 确认项目根目录的 settings.gradle 是否引入自定义创建的子模块

  1. 在子模块中编写测试用例,并观察在 Spring 源码中的断点是否生效

方式一:测试的工程引入编译打包后的源码包

把编译好的源码导入到工程中,这样可以在源码中写注释并且断点调试源码了。如果想让其他工程(或者maven工程)依赖自己注释过的源码包,需要进行如下操作:

  1. 使用 gradle 在将相关模块的源码打成 jar

  1. 在【Project】侧边栏中的【External Libraries】,选择源码测试工程所依赖的 spring 相应的版本,右键选择【Open Library Settings】

  1. 选择【Libraries】里的 spring 源码包,在 Classes、Sources、Annotations 中选择编译打包后的源码

  1. 选择 Classes、Sources,删除原来maven仓库的jar,改成使用源码编译后jar包

Tips: 这种方式唯一的好处就是可以使用 maven 来构建测试工程,然后引用编译后 class 包。但这种方式不好的地方是,如果源码有任何修改,需要重新编译打包,示例项目需要重新进行引用。

编译与测试可能出现的问题

程序包jdk.jfr不存在

下载源码后,修改了 Gradle 配置后,执行 gradlew :spring-oxm:compileTestJava 命令可能会报以下的错误

这个问题是因为 jdk.jfr 是 java9 后才有的模块,而 spring 源码 5.3.10 版本已经使用这个包,所以需要设置项目配置的 jdk 版本高于 9。目前本人是直接将本地换成的 JDK 11,然后就可以成功编译。注意IDE需要修改以下几个位置

Gradle 版本

如果在编译的时候出现以下问题,可以尝试升级 Gradle

测试模块无法找到其他子模块

在创建测试模块可能出现如下的错误,这是因为创建的模块位置不正确,最快的解决方法是,将模块删除,然后在 spring 源码目录下创建新的模块即可。

build 构建模块时出现 checkstyleMain

如果 build 之后可能会出现了错误,直接忽略即可

参考资源

I know where dry desert ends, green grass grows · MooN