源码地址:spring-framework-v5.2.22.RELEASE
官方文档:spring-framework-5.2.22.RELEASE-reference
为啥要编译源码?
- 用了这么多年的 Spring,没编译过源码怎么行!
 - 可以在源码加上自己的注释,阅读源码的一种方式;
 - 锻炼调试代码的能力,应为很多时候 debug 看代码更快;
 - 学习里面的设计模式,设计原则;
 - 面试 (▼へ▼メ);
 
前提准备:
- 安装 jdk1.8及以上
 - 准备 gradle 我使用的 6.8.3
 - 准备 IntelliJ IDEA 2022.2 (Ultimate Edition)
 - 下载 spring 源码:
 
接下来详细说明步骤:
解压后源码文件,先关注两个md 文件:README.md,import-into-idea.md ,
这两个文件说明了如何编译原码及导入开发工具中;
修改原码中的 gradle 配置文件
settings.gradle
settings.gradle 替换为阿里的镜像源;
pluginManagement {repositories {gradlePluginPortal()// maven { url 'https://repo.spring.io/plugins-release' }maven { url "https://maven.aliyun.com/repository/public" }}}
gradle.properties
增加下面的三项;
version=5.2.22.RELEASEorg.gradle.jvmargs=-Xmx1536Morg.gradle.caching=trueorg.gradle.parallel=true## 启用新的孵化模式org.gradle.configureondemand=true## 开启守护进程 通过开启守护进程,下一次构建的时候,将会连接这个守护进程进行构建,## 而不是重新fork一个gradle构建进程org.gradle.daemon=true## 这个配置是指定我们的jdk目录org.gradle.java.home=/Library/Java/JavaVirtualMachines/jdk1.8.0_271.jdk/Contents/Home
Mac 下查看 jdk 目录的命令:/usr/libexec/java_home -V
build.gradle
同样是添加阿里的镜像源;
repositories {mavenCentral()// maven { url "https://repo.spring.io/libs-spring-framework-build" }maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter'}}
预编译spring-oxm、spring-core
这两个模块在导入开发工具前,需要先编译下,命令如下所示:
./gradlew :spring-oxm:compileTestJava
➜ spring-framework-5.2.22.RELEASE ./gradlew :spring-oxm:compileTestJavafatal: 不是 git 仓库(或者任何父目录):.git> Task :spring-oxm:genJaxb[ant:javac] : warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last;set to false for repeatable buildsBUILD SUCCESSFUL in 2m 46s
./gradlew :spring-core:compileTestJava
➜ spring-framework-5.2.22.RELEASE ./gradlew :spring-core:compileTestJavafatal: 不是 git 仓库(或者任何父目录):.gitBUILD SUCCESSFUL in 12s17 actionable tasks: 2 executed, 15 up-to-date
出现两个 success 即表示成功。
如果你的代码不是 git 拉取的话,会有个 git 相关的报错不影响使用,见《一些报错》中的说明。
导入 IDEA
File —>New —>Project from Existing Sources,构建工具选择 gradle ,选择我们预编译好的源码;
它会进行一些列的配置,这个时候我们可以修改下 IDEA 的 gradle 配置;
配置 gradle user home,及下面的 Gradle projects 相关,见下图所示:
配置完毕出现 success 后,点击右侧 gradle 侧边栏上的刷新按钮,重载下所有项目等到 success ;
测试项目
- 新建一个子模块 spring-lich-test;
 - build.gradle,依赖下spring-context 测试即可; ```properties dependencies { compile(project(“:spring-context”)) testImplementation ‘org.junit.jupiter:junit-jupiter-api:5.8.1’ testRuntimeOnly ‘org.junit.jupiter:junit-jupiter-engine:5.8.1’ }
 
完整如下:
plugins { id ‘java’ }
group ‘org.springframework’ version ‘5.2.22.RELEASE’
repositories { mavenCentral() }
dependencies { compile(project(“:spring-context”)) testImplementation ‘org.junit.jupiter:junit-jupiter-api:5.8.1’ testRuntimeOnly ‘org.junit.jupiter:junit-jupiter-engine:5.8.1’ }
test { useJUnitPlatform() }
增加测试接口等测试代码:```javapackage cn.lichenghao.service;import org.springframework.stereotype.Component;/*** 测试接口** @author chenghao.li*/@Componentpublic class HelloService {public void say() {System.out.println("hello world");}}
测试,Hello World~
package cn.lichenghao.service;import org.springframework.context.annotation.AnnotationConfigApplicationContext;/*** 测试 Hello World** @author chenghao.li*/public class App {public static void main(String[] args) {AnnotationConfigApplicationContext context= new AnnotationConfigApplicationContext("cn.lichenghao.service");HelloService helloService = context.getBean(HelloService.class);helloService.say();}}
正常的话会打印如下:
15:14:55: Executing ':spring-lich-test:App.main()'...> Task :buildSrc:compileJava UP-TO-DATE> Task :buildSrc:compileGroovy NO-SOURCE> Task :buildSrc:pluginDescriptors UP-TO-DATE> Task :buildSrc:processResources UP-TO-DATE> Task :buildSrc:classes UP-TO-DATE> Task :buildSrc:jar UP-TO-DATE> Task :buildSrc:assemble UP-TO-DATE> Task :buildSrc:pluginUnderTestMetadata UP-TO-DATE> Task :buildSrc:compileTestJava NO-SOURCE> Task :buildSrc:compileTestGroovy NO-SOURCE> Task :buildSrc:processTestResources NO-SOURCE> Task :buildSrc:testClasses UP-TO-DATE> Task :buildSrc:test NO-SOURCE> Task :buildSrc:validateTaskProperties UP-TO-DATE> Task :buildSrc:check UP-TO-DATE> Task :buildSrc:build UP-TO-DATEConfiguration on demand is an incubating feature.fatal: 不是 git 仓库(或者任何父目录):.git> Task :spring-lich-test:processResources NO-SOURCE> Task :spring-expression:processResources UP-TO-DATE> Task :spring-core:cglibRepackJar UP-TO-DATE> Task :spring-aop:processResources UP-TO-DATE> Task :spring-beans:processResources UP-TO-DATE> Task :spring-core:objenesisRepackJar UP-TO-DATE> Task :spring-context:processResources UP-TO-DATE> Task :spring-core:processResources UP-TO-DATE> Task :spring-instrument:compileJava UP-TO-DATE> Task :spring-instrument:processResources NO-SOURCE> Task :spring-instrument:classes UP-TO-DATE> Task :spring-instrument:jar UP-TO-DATE> Task :kotlin-coroutines:compileKotlin UP-TO-DATE> Task :kotlin-coroutines:compileJava NO-SOURCE> Task :kotlin-coroutines:processResources NO-SOURCE> Task :kotlin-coroutines:classes UP-TO-DATE> Task :kotlin-coroutines:inspectClassesForKotlinIC UP-TO-DATE> Task :kotlin-coroutines:jar UP-TO-DATE> Task :spring-jcl:compileJava UP-TO-DATE> Task :spring-jcl:processResources UP-TO-DATE> Task :spring-jcl:classes UP-TO-DATE> Task :spring-jcl:jar UP-TO-DATE> Task :spring-core:compileKotlin UP-TO-DATE> Task :spring-core:compileJava UP-TO-DATE> Task :spring-core:classes UP-TO-DATE> Task :spring-core:inspectClassesForKotlinIC UP-TO-DATE> Task :spring-core:jar UP-TO-DATE> Task :spring-expression:compileKotlin UP-TO-DATE> Task :spring-expression:compileJava UP-TO-DATE> Task :spring-expression:classes UP-TO-DATE> Task :spring-expression:inspectClassesForKotlinIC UP-TO-DATE> Task :spring-expression:jar UP-TO-DATE> Task :spring-beans:compileGroovy UP-TO-DATE> Task :spring-beans:compileKotlin UP-TO-DATE> Task :spring-beans:compileJava NO-SOURCE> Task :spring-beans:classes UP-TO-DATE> Task :spring-beans:inspectClassesForKotlinIC UP-TO-DATE> Task :spring-beans:jar UP-TO-DATE> Task :spring-aop:compileJava UP-TO-DATE> Task :spring-aop:classes UP-TO-DATE> Task :spring-aop:jar UP-TO-DATE> Task :spring-context:compileKotlin UP-TO-DATE> Task :spring-context:compileJava UP-TO-DATE> Task :spring-context:compileGroovy NO-SOURCE> Task :spring-context:classes UP-TO-DATE> Task :spring-context:inspectClassesForKotlinIC UP-TO-DATE> Task :spring-context:jar UP-TO-DATE> Task :spring-lich-test:compileJava UP-TO-DATE> Task :spring-lich-test:classes UP-TO-DATE> Task :spring-lich-test:App.main()hello worldBUILD SUCCESSFUL in 3s35 actionable tasks: 1 executed, 34 up-to-date
一些报错
如果不是 git 拉取的项目,那么会有如下的报错:
Build scan background action failed.org.gradle.process.internal.ExecException:Process 'command 'git'' finished with non-zero exit value 128
不影响使用,如果你有强迫症的话,可以用 git 拉取项目;或者你可以 git 建一个空的项目然后把下载的原码放进去也行;
com.ibm.websphere:uow:6.0.2.17. ```properties :spring-tx:test: Could not find com.ibm.websphere:uow:6.0.2.17. Required by: project :spring-tx
Possible solution:
- Declare repository providing the artifact, see the documentation 
at https://docs.gradle.org/current/userguide/declaring_repositories.html
Build.gradle 增加<br />[https://maven.aliyun.com/repository/spring](https://maven.aliyun.com/repository/spring)```propertiesrepositories {mavenCentral()// maven { url "https://repo.spring.io/libs-spring-framework-build" }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/spring" }}
 
