最近稍微研究了一下spring
源码,看了不少资料发现不少大佬都是将spring
源码拉到本地,自己编译完成之后在源码里面直接写注释,当然也更方便了自己学习和调试。所以我也做了一次尝试,在此记录一下编译的过程和遇到的问题。
本地编译spring
源码我使用的个软件版本如下:
gradle
:6.8.3
spring
: 5.3.7-SNAPSHOT
jdk
:11.0.11
gradle
可以去gradle
官网下载所需版本的二进制包,我们选择gradle-6.8.3
即可。
下载解压完成之后配置一下环境变量就行。配置完环境变量执行gradle -v
查看:
有需要的话我们还可以配置一下gradle
本地仓库的目录(相当于maven的repo),新建一个环境变量GRADLE_USER_HOME
指定你本地的gradle
仓库地址。下图是我在Mac上的配置:
当然这一步不做也行,gradle
默认的本地仓库地址是~/.gradle
,至此gradle
的安装就完成了。
在github上搜索spring framework
的官方源代码:
这里要重点说一下,我们下载源码的时候用git clone
命令拉取代码,不要直接下载它的zip包,否则后续的编译会出现报错!!!,具体错误在本文第五节会讲到。
在拉代码之前最好把项目fork到我们自己的仓库
如果大家觉得在github上拉代码速度太慢,也可以从gitee
上clone,操作步骤跟上述一致。下载完成之后如下图所示。
下面我们需要逐步解释/修改一下上图红框中的文件:
maven { url "https://maven.aliyun.com/repository/public" }
修改完成后如下图:
3. 修改gradle.properties文件
version=5.3.7-SNAPSHOT org.gradle.jvmargs=-Xmx2048M org.gradle.caching=true org.gradle.parallel=true kotlin.stdlib.default.dependency=false ## 启用新的孵化模式 org.gradle.configureondemand=true ## 开启守护进程 通过开启守护进程,下一次构建的时候,将会连接这个守护进程进行构建,而不是重新fork一个gradle构建进程 org.gradle.daemon=true ## 这个配置是指定我们的jdk目录,其实我本地环境变量配置的是jdk1.8 ## 至于这里为什么要重新指定为jdk11,在文章第五节会解答 org.gradle.java.home=/Users/Shared/software/jdk-11.0.11.jdk/Contents/Home
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' } maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter'}
修改完成之后如下图:
根据import-into-idea.md中写到的要求,我们需要先进行两次预编译。
spring-oxm
$ ./gradlew :spring-oxm:compileTestJava
构建截图如下:
2. 预编译spring-core
$ ./gradlew :spring-core:compileTestJava
构建截图如下:
完成预编译之后我们就终于可以把spring
源码导入IDEA了~~
BUILD SUCCESSFUL
我们的spring源码项目就已经编译成功了!!看到这里,恭喜你,spring源码的编译终于成功了!接下来我们进行一下简单的验证。
build.gradle
文件plugins { id 'java' } group 'org.springframework' version '5.3.7-SNAPSHOT' repositories { mavenLocal() maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' } maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter'} mavenCentral() } dependencies { testCompile group: 'junit', name: 'junit', version: '4.12' implementation(project(":spring-context")) }
编译项目直到控制台出现BUILD SUCCESSFUL
。
2. 写代码
AService.java
的代码:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class AService { public void printA() { System.out.println("A"); } }
Main
代码:
import com.spring.demo.service.AService; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.spring.demo.service"); AService aService = context.getBean(AService.class); aService.printA(); } }
直接运行main方法
大功告成!!
最后再主要说一下在编译过程中我遇到的一些问题。
3.3节
中需要把java的版本改成jdk11。Build scan background action failed org.gradle.process.internal.ExecException: Process 'command 'git'' finished with non-zero exit value 128 at org.gradle.process.internal.DefaultExecHandle$ExecResultImpl.assertNormalExitValue(DefaultExecHandle.java:417) at org.gradle.process.internal.DefaultExecAction.execute(DefaultExecAction.java:38) at org.gradle.process.internal.DefaultExecActionFactory.exec(DefaultExecActionFactory.java:152) at io.spring.ge.BuildScanConventions.exec(BuildScanConventions.java:162) at io.spring.ge.BuildScanConventions.addGitMetadata(BuildScanConventions.java:111) at com.gradle.scan.plugin.internal.api.j.a(SourceFile:22) at com.gradle.scan.plugin.internal.api.k$a.a(SourceFile:112) at com.gradle.scan.plugin.internal.api.h.a(SourceFile:61) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:834)
如果spring源码包下载的是zip包,那就有可能出现这种问题,用git clone拉取源码这种问题便会解决。
3. 预编译成功,但在idea里面会出现testCompiler()不存在
具体报错信息:
Could not find method testCompile() for arguments [{xxx] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
这可能是你本地下载的gradle版本是7.0+,建议将gradle版本换成6.x,问题解决。
参考文章:https://www.cnblogs.com/mazhichu/p/13163979.html