- 推荐B站博主搭建的Spring5的源码阅读环境以及笔记
- 视频:https://www.bilibili.com/video/av61188907
- 笔记:http://note.youdao.com/ynoteshare1/index.html?id=c3f11aab5e0a0083709cc64984a3c41a&type=note
前期运行环境与工具准备
- JDK版本:1.8.0_162 (版本1.8就行,我的是1.8最新版,高于1.8的没试过)
- 下载地址:https://www.oracle.com/technetwork/cn/java/javase/downloads/jdk8-downloads-2133151-zhs.html
- GRADLE版本:4.10.3(也可用idea自带的gradle导入就行,如果自己安装需要配置相关环境)
注意:这里会有一个问题,就是如果我们创建的项目和Gradle版本冲突了怎么办,也就是说Spring需要的版本和我们下载的版本不一致时怎么办?
解决:我们先不配置Gradle,在本地打开 Spring 目录,在当前目录打开 cmd,输入命令:
gradlew :spring-oxm:compileTestJava
- 出现
BUILD SUCCESS
字样时说明构建成功,如下图所示- 在 Spring-frameword-5.1x/.gradle 目录中可以看到 4.10.3,那么下载4.10.3版本即可。
- 另外,如果电脑本身就有Gradle那么直接进行下一个板块的步骤,导入IDEA,在IDEA中编译 compileTestJava 即可,可以以看到相应的 Gradle 版本
- 当然下载好之后要重新配置 Gradle 的环境变量,我就是因为电脑本身就有 Gradle,弄了很多次都不行,最后重新下载对应版本的 Gradle 版本。
- 配置教程:https://www.cnblogs.com/linkstar/p/7899191.html
- 这里得再加一步,为了编译过程更快,我们为安装好的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 } } }
- Spring 源码版本:v5.1.X.RELEASE (目前最新版为:5.2.1.RELEASE,下载最好用VPN,不然很慢)
- 下载地址:https://github.com/spring-projects/spring-framework
- IntelliJ IDEA版本:IntelliJ IDEA 2018.2.5(2017也可以,我的是2018)
- 下载地址:https://www.jetbrains.com/idea/download/
- 系统:WINDOWS 10
下载源码
- 我这里选择的是5.1.x版本的Spring,然后点击Clone or download,如果会Git可以使用Git命令的方式,不会的话选择下载ZIP压缩包,下载好之后需要解压
- 解压好之后,我们为 Spring 添加阿里云镜像
- 在编译过程中,Spring会去自动下载一些依赖的包,默认使用的是官方的镜像,下载比较慢,所以我们提前添加好国内镜像,将下面这行代码粘贴到
build.gradle
文件中的repositories
节点下即可//添加阿里云镜像 maven { url "http://maven.aliyun.com/nexus/content/groups/public" }
导入IDEA
- 点击File->New->Project form Existing Sources...打开项目
- 选择刚刚解压的spring项目工程
- 选择 Gradle
- 选择自己配置的Gradle环境
- 调整内存:-XX:MaxPermSize=2048m -Xmx2048m -XX:MaxHeapSize=2048m
- 点击Finish
注意:在点击finish前,最好是能够开启VPN,构建过程会要下载大量的依赖包跟插件,这里下载要很长时间我当时没有及时,做好去吃个饭,回来就差不多了,吃得快的可以再吃一顿,反正很慢。
下载过程:
项目导入到IDEA成功,如下图所示:
开始准备编译
- 修改docs.gradle文件
- 打开docs.gradle文件准备修改
- 注释掉dokka和asciidoctor两个配置项
- 因为在构建过程中执行这两个任务时会导致构建失败,这两个任务主要是用来生成文档使用,对主流程并没有任何影响,可以直接忽略,当然如果大家本地没有这个问题,也可以不注释。
- 替换docs.gradle文件中的task schemaZip配
- 在gradle的构建脚本,只针对Linux系统做了适配,需要把task schemaZip替换成下面代码,因为原有代码的路径符号" / "是针对Linux的,windows使用会有问题,在windows环境需要替换成" \\ ",否则会出现异常。
- 参考如下代码,注释部分是原有的代码:
//这部分被替换了,所以需要被替换掉 //task schemaZip(type: Zip) { // group = "Distribution" // baseName = "spring-framework" // classifier = "schema" // description = "Builds -${classifier} archive containing all " + // "XSDs for deployment at https://springframework.org/schema." // duplicatesStrategy 'exclude' // moduleProjects.each { subproject -> // def Properties schemas = new Properties(); // // subproject.sourceSets.main.resources.find { // (it.path.endsWith("META-INF/spring.schemas") || it.path.endsWith("META-INF\\spring.schemas")) // }?.withInputStream { schemas.load(it) } // // for (def key : schemas.keySet()) { // def shortName = key.replaceAll(/http.*schema.(.*).spring-.*/, '$1') // assert shortName != key // File xsdFile = subproject.sourceSets.main.resources.find { // (it.path.endsWith(schemas.get(key)) || it.path.endsWith(schemas.get(key).replaceAll('\\/','\\\\'))) // } // assert xsdFile != null // into (shortName) { // from xsdFile.path // } // } // } //} //替换成如下代码即可 task schemaZip(type: Zip) { group = "Distribution" baseName = "spring-framework" classifier = "schema" description = "Builds -${classifier} archive containing all " + "XSDs for deployment at http://springframework.org/schema." duplicatesStrategy 'exclude' moduleProjects.each { subproject -> def Properties schemas = new Properties(); subproject.sourceSets.main.resources.find { it.path.endsWith("META-INF\\spring.schemas") }?.withInputStream { schemas.load(it) } for (def key : schemas.keySet()) { def shortName = key.replaceAll(/http.*schema.(.*).spring-.*/, '$1') assert shortName != key File xsdFile = subproject.sourceSets.main.resources.find { it.path.endsWith(schemas.get(key).replaceAll('\\/','\\\\')) } assert xsdFile != null into (shortName) { from xsdFile.path } } } }
- 到现在编译前的准备工作才算完成
根据import-into-idea.md文档步骤去构建
- 打开spring工程的import-into-idea.md文件
- import-into-idea.md里面详细的描述了编译步骤,根据import-into-idea.md文档里面介绍,我们需要对spring-core和spring-oxm做预编译
- 预编译
- 在IDEA中预编译很简单,按下图操作即可:
- 注意:如果右侧没有Gradle那么可以在View中让它显示
- 出现如下图所示,表示预编译成功
- 上边的过程演示了 :spring-oxm 的预编译,:spring-core和它同理这里就不演示了,成功显示如下图即可
- 终极编译
- 对整个Spring项目构建,这个时候它会自动下载依赖包,如果有异常,会在控制台抛出并停止操作,编译整个工程,需要20分钟左右的时间。
- 构建成功在控制台可以看到下图提示
执行单元测试
- 即使整个项目没有Error或者红点,也不代表项目已经成功构建好了,我们还需要执行个单元测试试下,如果能顺利执行单元测试,那证明该项目已经构建成功,这里我用到的是DispatcherServletTests这个类,直接运行查看结果:
- 我第一次执行的时候报错了,错误如下:
- 网上找了很多解决办法还是没用
- 比如这个:
- 结果出来的错误更离谱,网上根本找不到相关示例,最后实在是找不到只能重新再来一次
- 还有这个:
- 这个还是不行,虽然报错没有更离谱,但是还是会有错误,只是错误没有改变罢了
- 还有这个:
- 这个还是不行,把这个类注释掉,那么还会有其他类报错,最后根本注释不完
- 最后我也找了很久,终于让我找到了
- 视频参考:https://www.bilibili.com/video/av76404922
- 解决办法就是将找不到符号的那个类的子模块的build文件删除,再次重新build一遍即可,如果还是不行那么把该模块的text文件中的代码重新运行run一遍,之后再运行测试类即可。之后如果还是显示找不到符号,重复上述步骤即可。
- 看完视频我的使用视频中的方式,之后还是会有其他的报错,但是报的错都是找不到符号,我还是使用同样的方法,进行重新rebuild,之后再将text中的类重新运行run一遍即可。
- 很明显,上面单元测试类的所有单测执行成功。
- 当我第二次安装的时候又遇到了不一样的坑
- 在编译 spring-aspect 的 javadoc 时我等了半个多小时还是不动,之后又重新弄了很多次,还是不行。
- 解决:注释掉 build.gradle 中的一些代码:
// javadoc { // description = "Generates project-level javadoc for use in -javadoc jar" // // options.encoding = "UTF-8" // options.memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED // options.author = true // options.header = project.name // options.use = true // options.links(project.ext.javadocLinks) // options.addStringOption("Xdoclint:none", "-quiet") // // // Suppress warnings due to cross-module @see and @link references. // // Note that global 'api' task does display all warnings. // logging.captureStandardError LogLevel.INFO // logging.captureStandardOutput LogLevel.INFO // suppress "## warnings" message // } task sourcesJar(type: Jar, dependsOn: classes) { duplicatesStrategy = DuplicatesStrategy.EXCLUDE classifier = "sources" from sourceSets.main.allSource // Don't include or exclude anything explicitly by default. See SPR-12085. } // task javadocJar(type: Jar) { // classifier = "javadoc" // from javadoc // } artifacts { archives sourcesJar // archives javadocJar } }
然后暂停当前运行,重新 build 即可。
可能遇到的坑点回顾
- 构建成功没报错,但运行单元测试有异常 ,提示类找不到
- 方案1:尝试点击右边菜单栏projects刷新项目,然后对Spring(Root)模块先clean再build一次
- 方案2:针对找不到类的模块重新build一次
- 方案3:点击Spring(root)模块下的Tasks->other->compileTestJava 执行一遍,针对test类编译一次即可
- 构建失败,缺少依赖包
- 方案1:对Spring(Root)模块先clean再build一次(建议打开VPN,有可能存在某些包下载不成功导致)
- 方案2:尝试针对当前模块执行buildDependents
- 构建失败,执行gradle task失败
- 方案1:可能是当前运行环境版本不支持问题,如果不重要的问题,可以注释掉,保证构建正常
- 构建失败,编码异常
- 方案1:可以通过idea工具设置:Editor-File encodings 全部设置为UTF-8
有兴趣的同学可以关注我的个人公众号,期待我们共同进步!!!