源码地址: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.RELEASE
org.gradle.jvmargs=-Xmx1536M
org.gradle.caching=true
org.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:compileTestJava
fatal: 不是 git 仓库(或者任何父目录):.git
> Task :spring-oxm:genJaxb
[ant:javac] : warning: 'includeantruntime' was not set
, defaulting to build.sysclasspath=last;
set to false for repeatable builds
BUILD SUCCESSFUL in 2m 46s
./gradlew :spring-core:compileTestJava
➜ spring-framework-5.2.22.RELEASE ./gradlew :spring-core:compileTestJava
fatal: 不是 git 仓库(或者任何父目录):.git
BUILD SUCCESSFUL in 12s
17 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() }
增加测试接口等测试代码:
```java
package cn.lichenghao.service;
import org.springframework.stereotype.Component;
/**
* 测试接口
*
* @author chenghao.li
*/
@Component
public 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-DATE
Configuration 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 world
BUILD SUCCESSFUL in 3s
35 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)
```properties
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'}
maven { url "https://maven.aliyun.com/repository/spring" }
}