Spring源码学习 之 调试环境配置
目录
1.4 创建测试module测试我们编译的Spring源码是否可以正常调用
Spring框架号称是java开发工程师“春天”的框架,已经成为事实上行业标准的框架。其优秀的代码设计使用了大量的设计模式以及很多给人启发的大师的设计。由于工作背景从C语言切换到Java,且没有比较大型java项目的开发经验,所以决定学习一下Spring源码。
我自己也是还在Spring源码的学习过程中,以这个博客作为自己学习过程中的一个记录。首先是这一部分学习的第一个章节:
1.Spring debug环境配置
1.1 首先是我本地所有需要的工具以及版本:
(1)MacBook Air (这个就不强求了,因为我这手头就这一台电脑,使用windows只是idea的菜单按钮不太一样,以及工具的安装方式不太一样)
(2)Idea 社区版2021 (直接用最新的吧,网上查询资料说低版本的idea可能会影响编译,我这里直接使用的最新版本的idea,我当时安装的时候是在2021年配置的,第一次重复不要轴)
(3)Spring源码版本 5.3.8(此处直接使用git下载源码zip包就可以了,国外的github网速比较慢,可以直接使用国内的gitee地址下载,gitee每天都会同步github上的源码,所以不必担心源码不是最新的)
(4)jdk版本11.0.12 (虽说官网上说了可以使用jdk8以上的版本进行编译,但是第二次重复不要轴,直接安装jdk11,后续会看到有一个必须使用jdk11才能过去的坑)
(5)gradle版本 6.8.3(这里gradle的版本不是随意选的,其实是Spring不同版本的源码会指定不同的gradle版本进行编译,所以还是那句话,不要轴)
1.2 导入idea工程之前的准备工作:
准备工作:
(1)jdk11下载:
下载地址可以使用如下地址,oracle官网下载太慢,而且需要账号。不用谢我!!
华为云jdk各版本高速下载通道:Index of java-local/jdk
(2)Spring 5.3.8下载地址:
https://github.com/spring-projects/spring-framework/releases
(3)gradle版本指定位置,以及配置从本地拿取gradle软件
前面说过spring源码对应的gradle版本是在配置文件中指定好的,需要使用对应的gradle版本才可以。具体指定的配置文件如下:
/Users/xxxx/code/spring-framework-5.3.8/gradle/wrapper
我的spring源码下载位置是在/Users/xxxx/code/spring-framework-5.3.8,在/Users/xxxx/code/spring-framework-5.3.8/gradle/wrapper目录下存在一个配置文件
gradle-wrapper.properties
配置文件内容如下:
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
我们如果不进行配置,则会自动从distributionUrl指定的网址下载对应版本的gradle软件。我们可以看到spring-5.3.8对应的gradle版本就是gradle-6.8.3 如果我们不进行配置,则会从这个国外网站下载gradle,我们可以将这个配置值配置为我们本地的gradle压缩包,这样就不会从远端下载,而是直接使用本地指定gradle版本。
配置值如下:
distributionUrl=file\:///Users/xxxx/Desktop/tool/gradle-6.8.3-all.zip
(4)gradle仓库下载地址配置:
同样的原因,由于spring依赖的jar包太多,工程起来之后,会从远端下载海量依赖,如果从国外下载依赖,那么时间太长甚至会掉线导致工程构建失败。我们可以将gradle依赖下载地址指定为阿里的依赖库,提高下载速度。
阿里仓库地址:https://developer.aliyun.com/mvn/guide
需要将这两个仓库地址添加一下:
具体需要修改的文件以及内容如下:
/Users/xxxx/code/spring-framework-5.3.8/build.gradle
/Users/xxxx/code/spring-framework-5.3.8/settings.gradle
(5)下载Kotlin插件
(6)在将Spring源码导入到idea之前,我们还有一些准备工作需要做。
在Spring源码中提供了导入ide开发工具的md文档,主要是这两个文件
我们将要导入的是idea,所以查看一下下面的md文件,文件中提到由于其它组件对于spring-oxm以及spring-core组件有依赖,所以我们需要提前编译这两个组件。
具体需要到这两个组件对应的代码目录下,执行如下gradle命令,完成这两个组件的预编译。
./gradlew :spring-oxm:compileTestJava
./gradlew :spring-core:compileTestJava
1.3 Idea导入Spring源码
(1)采用下面方式导入工程
然后使用gradle方式导入源码
导入完成后,系统就会自动导入依赖
1.4 创建测试module测试我们编译的Spring源码是否可以正常调用
(1)由于我们的Spring项目采用的是gradle的方式进行编译,所以我们新建项目的时候,需要采用gradle的方式进行创建。
(2)测试模块创建完成后,需要到该测试模块的gradle配置文件中添加对于spring-context组件的依赖
(3)测试项目的代码结构以及内容如下:
AppConfig.java
package com.whq.config;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.whq")
public class AppConfig {
}
HelloService.java
package com.whq.service;
import org.springframework.stereotype.Service;
@Service
public class HelloService {
public void Hello(){
System.out.println("Hello, World");
}
}
SpringTest.java
package com.whq;
import com.whq.config.AppConfig;
import com.whq.service.HelloService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class SpringTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
HelloService helloService = ac.getBean(HelloService.class);
helloService.Hello();
}
(4)代码编译方式修改
如果不进行修改,默认idea是采用gradle的方式,进行编译,然后输出测试module主函数的输出内容,但是这种方式比较慢,我们可以通过修改配置,直接采用idea自带的方式进行编译,提高编译速度,配置方式如下图第二个红框所示
其它两项配置推荐读者同样配置好。
这两个配置的含义是:
第一个配置指定的是gradle的安装目录,我这里没有修改,固定安装在用户目录的 .gradle目录下
第二个配置指定的是gradle的具体安装位置以及gradle的jvm版本,这里我们指定的是我们本地安装的gradle目录。
但是读者可能奇怪的是,我们其实没有安装过gradle,怎么指定gradle的安装目录,
前面我们进行了一项配置,指定了需要安装的gradle的zip路径。然后Spring源码下载依赖的时候,会获取到我们指定的gradle压缩包,然后解压安装到
我们此处指定的gradle home下,具体安装目录如下
/Users/xxxx/.gradle/wrapper/dists/gradle-6.8.3-bin/7ykxq50lst7lb7wx1nijpicxn/gradle-6.8.3
其中7ykxq50lst7lb7wx1nijpicxn 这个是随机生成的,每个人应该不一样。目录就将这个地址填入就行。
对于配置jdk11的原因,是后续代码编译的时候会报一个类找不到的错误,原因是这个类是在jdk11中才有定义,jdk8中没有,需要配置此处的一个jdk版本。
同时更重要的是需要指定项目jdk编译的版本类型为11,所以还需要配置项目的jdk编译版本,如下:
(5)其实在编写测试module代码中,就可以看到Spring源码是否导入成功。
具体方式是当我们调用AnnotationConfigApplicationContext 以及使用@Configuration时候,idea是否有提示。如果有提示的话,代表最起码源码导入成功了,已经很接近成功了。如果没有提示,那就麻烦了,我想当初调试的时候,这个部分也是卡主我好几天,直到现在也没有找到根本解决的方法,大家如果有解决方法可以在评论中分享一下。
后来,我找到一个规避方法,就是在创建一个新的测试项目,然后发现原来的测试项目中,idea就会提示这些类,但是新增的项目还是没有提示。 哈哈哈哈。 我猜想可能是那个地方我还是没有配置到位,导致没有及时刷新依赖。但是新建一个module后,项目整个刷新,就会导致原先新增的项目中的依赖刷新完成,可以正常使用。
1.5 Spring源码编译中遇到的一些问题。
(1)Spring源码编译Java: 找不到符号 InstrumentationSavingAgent
这个问题,我是参考了这篇博文解决的,感谢大神分享:
Spring源码编译Java: 找不到符号 InstrumentationSavingAgent_雪子的博客-CSDN博客
(2)Error:(354, 51) java: 找不到符号
符号: 变量 CoroutinesUtils
位置: 类 org.springframework.core.ReactiveAdapterRegistry.CoroutinesRegistrar
这个问题,我是参考了这篇博文解决的,感谢大神分享:
【spring源码系列-0】spring源码下载、编译、debug_蚂蚁要上天的博客-CSDN博客
这篇博文的问题解决方法真是解决了我的燃眉之急,文章中还介绍了其它问题的解决方法,但是我没有遇到过,大家可以参考。
因为写这篇文章的时候,已经是在我搭建好环境一个月之后了,搭建过程中好多问题,我都已经忘记了,只是记录了一些比较典型的问题,大家如果有其他问题,欢迎在评论中提出来,我们一起参照解决。
后续,我会继续分享一些我学习spring源码的心得体会,感谢大家的浏览查阅。
欢迎关注我的公众号:风云编程录
欢迎想深入学习编程知识,探究底层原理或者了解开发工程师工作趣事的同学加入我的知识星球,刚刚开通,正在梳理内容,后续保证干货很多,欢迎关注!