Spring源碼學(xué)習(xí)之IDEA搭建Spring源碼Debug環(huán)境
一、前言
大家肯定都debug過spring的源碼,看看bean的創(chuàng)建過程,有個(gè)缺點(diǎn)不能自己隨意的添加注釋。
學(xué)習(xí)開源框架的源碼時(shí),搭建一個(gè)可以方便地進(jìn)行調(diào)試的環(huán)境是非常重要的,不明白的地方也可以修改一下源碼的東西!
看了好多文章,都是比較老的,現(xiàn)在跟著搭建是有問題的,踩了很多坑,最終完成搭建,整理一下思路還是比較清晰的,讓我們一起來試試吧!
二、下載導(dǎo)入Idea
本次小編使用的Idea版本為2021.3,不太建議使用低版本的。
1、下載源碼
可以通過github或者gitee進(jìn)行下載,也可以直接clone,文件比較大,這里建議直接下載好在Idea中打開即可!
由于Spring6需要JDK17,短時(shí)間也不會(huì)使用到,我們還是以Spring5的源碼來學(xué)習(xí)哈,本地下載的Spring版本為:5.3.X
Spring5.3.X下載地址:https://github.com/spring-projects/spring-framework/tree/5.3.x
解壓完成:
2、導(dǎo)入Idea
因?yàn)镾pring官方已經(jīng)把Gradle作為構(gòu)建依賴的工具了,網(wǎng)上有好多都要下載Gradle進(jìn)行配置的,其實(shí)Idea是會(huì)幫我們下載并應(yīng)用的,我們只需要把源碼導(dǎo)入靜靜的等待Idea表演即可!
這時(shí)我們把項(xiàng)目導(dǎo)入到Idea中:
這里我們選中Gradle。
點(diǎn)擊相信項(xiàng)目:
小編不是第一次加載,所以很快,第一次的時(shí)候已經(jīng)下載過Gradle
了,專門導(dǎo)入一個(gè)新的讓大家看一下:
稍等三五分組就構(gòu)建成功了!
我們來說一下怎么知道下載那個(gè)版本的Gradle呢?
「Spring5.3.X是需要gradle-7.5.1-bin.zip」
如果想下載Gradle源碼的可以去下載你想要的版本,這種帶all的才是有源碼的哈!
Gradle下載地址:https://services.gradle.org/distributions/
三、項(xiàng)目完善
現(xiàn)在已經(jīng)構(gòu)建完成了,我們現(xiàn)在需要新建一個(gè)模塊,去使用我們剛剛構(gòu)建的spring源碼即可!
1、新建Module
我們新建一個(gè)Gradle模塊:
指定父模塊和名稱:
我們可以查看一下目錄下的settings.gradle文件是否新增成功,我們看到include 'myspring',說明我們已經(jīng)新增模塊成功!
2、新模塊導(dǎo)入依賴
這里是個(gè)大坑,坑了我一天,所有的教程都是使用compile來導(dǎo)入依賴的,但是之前使用的Gradle版本都是7.0之前的,之前肯定沒有問題,現(xiàn)在我們使用的是7.5.1。compile命令是被棄用的,不要問我咋知道的,我問的chatGPT,知道他不靠譜但是沒有辦法只能試一下,果然好用!!
「compile關(guān)鍵字用于導(dǎo)入依賴項(xiàng)的語法在Gradle 7.0及更早版本中是有效的。但是,從Gradle 7.0開始,官方推薦使用implementation代替compile」。
「自從Gradle 7.0起,compile被棄用,并建議使用implementation、api、compileOnly等配置選項(xiàng)代替,以提供更清晰的依賴管理和構(gòu)建性能優(yōu)化?!?。
我們添加一些主要的依賴,為了少些getset方法,我們?cè)谔砑右幌翷ombok!
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 versinotallow="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、測(cè)試Bean
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、測(cè)試類
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!
如果使用中文就會(huì)亂碼,我們改一下字符集還是不行,加上Gradle字符集還是不行!有知道的大佬歡迎分享一下哈~~
打了斷點(diǎn),spring內(nèi)部是正確顯示的:
獲取到的也是正確的,就是輸出的時(shí)候亂碼!
這個(gè)對(duì)我們調(diào)試源碼沒有什么影響的!
6、源碼跟進(jìn)
我們按住Ctrl進(jìn)入源碼:
我們可以看到已經(jīng)是我們自己下載的源碼了,這樣就可以本地debug學(xué)習(xí)了哈!
大家可以好好學(xué)習(xí)源碼了哈!
我們看到在控制臺(tái)輸入一些報(bào)錯(cuò)信息,其實(shí)就是git的 問題:
zip 發(fā)行版旨在共享我們的源代碼,但不一定用于構(gòu)建它。構(gòu)建的這一部分依賴于構(gòu)建管道中存在的 git 文件。
解決方案就是clone項(xiàng)目,不要使用下載的方式,不過這個(gè)對(duì)我們調(diào)試代碼沒有任何影響哈!
Github官方回復(fù)地址:
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)
四、總結(jié)
通過搭建Spring源碼Debug環(huán)境,我們能夠更深入地了解Spring框架的運(yùn)行機(jī)制,并通過實(shí)際調(diào)試經(jīng)驗(yàn)加深對(duì)其內(nèi)部工作原理的理解。這種深入學(xué)習(xí)可以幫助我們更好地應(yīng)用和開發(fā)Spring框架,同時(shí)也提升了我們解決問題的能力。
我們看這種實(shí)時(shí)性的博客教程還是要看最新的,要不可能會(huì)有一些不適合新版的!
希望這篇博客對(duì)你有所幫助,祝你在學(xué)習(xí)Spring源碼過程中取得成功!