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源码过程中取得成功!


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

相关推荐
瓜牛_gn13 分钟前
依赖注入注解
java·后端·spring
一元咖啡1 小时前
SpringCloud Gateway转发请求到同一个服务的不同端口
spring·spring cloud·gateway
java亮小白19973 小时前
Spring循环依赖如何解决的?
java·后端·spring
苏-言3 小时前
Spring IOC实战指南:从零到一的构建过程
java·数据库·spring
草莓base4 小时前
【手写一个spring】spring源码的简单实现--容器启动
java·后端·spring
冰帝海岸10 小时前
01-spring security认证笔记
java·笔记·spring
没书读了11 小时前
ssm框架-spring-spring声明式事务
java·数据库·spring
代码小鑫14 小时前
A043-基于Spring Boot的秒杀系统设计与实现
java·开发语言·数据库·spring boot·后端·spring·毕业设计
真心喜欢你吖14 小时前
SpringBoot与MongoDB深度整合及应用案例
java·spring boot·后端·mongodb·spring
斗-匕16 小时前
Spring事务管理
数据库·spring·oracle