Spring源码学习之IDEA搭建Spring源码Debug环境

一、前言

大家肯定都debug过spring的源码,看看bean的创建过程,有个缺点不能自己随意的添加注释。

学习开源框架的源码时,搭建一个可以方便地进行调试的环境是非常重要的,不明白的地方也可以修改一下源码的东西!

看了好多文章,都是比较老的,现在跟着搭建是有问题的,踩了很多坑,最终完成搭建,整理一下思路还是比较清晰的,让我们一起来试试吧!

二、下载导入Idea

本次小编使用的Idea版本为2021.3,不太建议使用低版本的。

1. 下载源码

可以通过github或者gitee进行下载,也可以直接clone,文件比较大,这里建议直接下载好在Idea中打开即可!

由于Spring6需要JDK17,短时间也不会使用到,我们还是以Spring5的源码来学习哈,本地下载的Spring版本为:5.3.X

Spring5.3.X下载地址

解压完成:

2. 导入Idea

因为Spring官方已经把Gradle作为构建依赖的工具了,网上有好多都要下载Gradle进行配置的,其实Idea是会帮我们下载并应用的,我们只需要把源码导入静静的等待Idea表演即可!

这时我们把项目导入到Idea中:

这里我们选中Gradle

点击相信项目:

小编不是第一次加载,所以很快,第一次的时候已经下载过Gradle了,专门导入一个新的让大家看一下:

稍等三五分组就构建成功了!

我们来说一下怎么知道下载那个版本的Gradle呢?

Spring5.3.X是需要gradle-7.5.1-bin.zip

如果想下载Gradle源码的可以去下载你想要的版本,这种带all的才是有源码的哈!

Gradle下载地址

三、项目完善

现在已经构建完成了,我们现在需要新建一个模块,去使用我们刚刚构建的spring源码即可!

1. 新建Module

我们新建一个Gradle模块:

指定父模块和名称:

我们可以查看一下目录下的settings.gradle文件是否新增成功,我们看到include 'myspring',说明我们已经新增模块成功!

2. 新模块导入依赖

这里是个大坑,坑了我一天,所有的教程都是使用compile来导入依赖的,但是之前使用的Gradle版本都是7.0之前的,之前肯定没有问题,现在我们使用的是7.5.1。compile命令是被弃用的,不要问我咋知道的,我问的chatGPT,知道他不靠谱但是没有办法只能试一下,果然好用!!

compile关键字用于导入依赖项的语法在Gradle 7.0及更早版本中是有效的。但是,从Gradle 7.0开始,官方推荐使用implementation代替compile

自从Gradle 7.0起,compile被弃用,并建议使用implementation、api、compileOnly等配置选项代替,以提供更清晰的依赖管理和构建性能优化。

我们添加一些主要的依赖,为了少些getset方法,我们在添加一下Lombok!

xml 复制代码
implementation(project(":spring-context"))
implementation(project(":spring-beans"))
implementation(project(":spring-core"))
implementation(project(":spring-aop"))
compileOnly 'org.projectlombok:lombok:1.18.20'
annotationProcessor 'org.projectlombok:lombok:1.18.20'

记得刷新依赖!

3. spring.xml文件配置

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="test" class="com.test.bean.Test">
		<property name="id" value="100"></property>
		<property name="name" value="Tom"></property>
    </bean>
</beans>

4. 测试Bean

java 复制代码
public class Test {

	private Long id;

	private String name;

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "Test{" +
				"id=" + id +
				", name='" + name + '\'' +
				'}';
	}
}

5. 测试类

java 复制代码
public class SpringMain {

	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
		Test test = context.getBean("test", Test.class);
		System.out.println(test);
	}
}

我们看到正常输出Bean!

如果使用中文就会乱码,我们改一下字符集还是不行,加上Gradle字符集还是不行!有知道的大佬欢迎分享一下哈~~

打了断点,spring内部是正确显示的:

获取到的也是正确的,就是输出的时候乱码!

这个对我们调试源码没有什么影响的!

6. 源码跟进

我们按住Ctrl进入源码

我们可以看到已经是我们自己下载的源码了,这样就可以本地debug学习了哈!

大家可以好好学习源码了哈!

我们看到在控制台输入一些报错信息,其实就是git的 问题:

zip 发行版旨在共享我们的源代码,但不一定用于构建它。 构建的这一部分依赖于构建管道中存在的 git 文件。

解决方案就是clone项目,不要使用下载的方式,不过这个对我们调试代码没有任何影响哈!

Github官方回复地址

java 复制代码
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:415)
	at org.gradle.process.internal.DefaultExecAction.execute(DefaultExecAction.java:38)
	at org.gradle.process.internal.DefaultExecActionFactory.exec(DefaultExecActionFactory.java:202)
	at io.spring.ge.conventions.gradle.WorkingDirectoryProcessOperations.exec(WorkingDirectoryProcessOperations.java:45)
	at io.spring.ge.conventions.gradle.ProcessOperationsProcessRunner.run(ProcessOperationsProcessRunner.java:40)
	at io.spring.ge.conventions.gradle.BuildScanConventions.run(BuildScanConventions.java:195)
	at io.spring.ge.conventions.gradle.BuildScanConventions.addGitMetadata(BuildScanConventions.java:139)
	at com.gradle.enterprise.gradleplugin.internal.extension.a$4.run(SourceFile:172)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)

四、总结

通过搭建Spring源码Debug环境,我们能够更深入地了解Spring框架的运行机制,并通过实际调试经验加深对其内部工作原理的理解。这种深入学习可以帮助我们更好地应用和开发Spring框架,同时也提升了我们解决问题的能力。

我们看这种实时性的博客教程还是要看最新的,要不可能会有一些不适合新版的!

希望这篇博客对你有所帮助,祝你在学习Spring源码过程中取得成功!


看到这里了,还请动一下您的发财小手,关注一下公众号:『小王博客基地』!!谢谢您的关注!!文章首发看!!!

相关推荐
暮乘白帝过重山4 分钟前
Singleton和Prototype的作用域与饿汉式/懒汉式的初始化方式
spring·原型模式·prototype·饿汉式·singleton·懒汉式
ejinxian34 分钟前
Spring AI Alibaba 快速开发生成式 Java AI 应用
java·人工智能·spring
杉之39 分钟前
SpringBlade 数据库字段的自动填充
java·笔记·学习·spring·tomcat
圈圈编码1 小时前
Spring Task 定时任务
java·前端·spring
爱的叹息1 小时前
Java 连接 Redis 的驱动(Jedis、Lettuce、Redisson、Spring Data Redis)分类及对比
java·redis·spring
松韬2 小时前
Spring + Redisson:从 0 到 1 搭建高可用分布式缓存系统
java·redis·分布式·spring·缓存
天上掉下来个程小白2 小时前
Redis-14.在Java中操作Redis-Spring Data Redis使用方式-操作列表类型的数据
java·redis·spring·springboot·苍穹外卖
汤姆大聪明3 小时前
Redisson 操作 Redis Stream 消息队列详解及实战案例
redis·spring·缓存·maven
正经摸鱼5 小时前
classpath与classpath*实现逻辑
后端·spring
良枫5 小时前
Spring Security认证授权深度解析
spring boot·spring