小编在最近几个月中工作实在比较忙,本来这篇文章会在好几个月前发布,但是项目比较急,前天刚刚通宵上线项目,现在的空余时间很多,为此编写该文章,帮助大家通过源码的方式学习Spring,学习Spring一定要学会改源码,通过源码来验证自己的猜测,这样你会记住很多,话不多说,开整!!!
目录
一、下载Gradle-配置环境变量
下载Gradle前,先到Spring官网下载源码:https://github.com/spring-projects/spring-framework/tags,解压,进入到目录:
spring-framework-5.3.26\spring-framework-5.3.26\gradle\wrapper
查看 gradle-wrapper.properties 文件,下图中,distributionUrl对应的则为当前Spring源码版本对应的Gradle版本。
Spring中部分源码是基于Gradle环境的,所以这里必须下载Gradle的,与maven一个道理,都是管理依赖包的。
小编使用的工具版本介绍:IntelliJ IDEA版本为2020.3.4、Gradle版本为7.5.1
Gradle下载地址:
Gradle | Releases,我这里直接下载7.5.1版本配置Gradle环境变量一:
变量名:GRADLE_HOME
变量值:E:\gradle-7.5.1 (这里是我本地的gradle路径)
配置Gradle环境变量二:
变量名:GRADLE_USER_NAME
变量值:E:\gradle-repository (这里配置的是gradle的仓库地址)
配置Gradle环境变量三,配置 Path:
环境变量值:%GRADLE_HOME%\bin
配置Tomcat环境变量四,如果使用Spring源码深入SpringMVC的话,则需要配置Tomcat:
变量名:CATALINA_HOME
变量值:E:\tomcat\apache-tomcat-9.0.76
path环境变量配置:%GRADLE_HOME%\bin
验证Gradle是否安装成功:
二、Spring项目源码配置Gradle环境
先去Spring官网下载源码,并导入到编译器中,我使用的Spring版本为:spring-framework-5.3.26.
https://github.com/spring-projects/spring-framework/tags
2.1、IntelliJ IDEA配置Gradle
2.2、Spring源码项目更改Gradle配置文件
settings.gradle文件更改内容:
pluginManagement {
repositories {
//新增远程仓库地址为国内,阿里巴巴。
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
mavenCentral()
gradlePluginPortal()
maven { url "https://repo.spring.io/release" }
}
}
build.gradle文件更改内容:
//292行repositories代码块内容变更为:
repositories {
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' }
mavenCentral()
maven { url "https://repo.spring.io/libs-spring-framework-build" }
}
配置完毕后,开始build项目,Gradle开始下载一些相关文件,下载完毕后会出现以下信息:
Starting Gradle Daemon...
Gradle Daemon started in 2 s 826 ms
fatal: not a git repository (or any of the parent directories): .git
> Task :buildSrc:compileJava UP-TO-DATE
> Task :buildSrc:compileGroovy NO-SOURCE
> Task :buildSrc:pluginDescriptors UP-TO-DATE
> Task :buildSrc:processResources UP-TO-DATE
> Task :buildSrc:classes UP-TO-DATE
> Task :buildSrc:jar UP-TO-DATE
> Task :buildSrc:generateSourceRoots UP-TO-DATE
> Task :buildSrc:assemble UP-TO-DATE
> Task :buildSrc:pluginUnderTestMetadata UP-TO-DATE
> Task :buildSrc:compileTestJava NO-SOURCE
> Task :buildSrc:compileTestGroovy NO-SOURCE
> Task :buildSrc:processTestResources NO-SOURCE
> Task :buildSrc:testClasses UP-TO-DATE
> Task :buildSrc:test SKIPPED
> Task :buildSrc:validatePlugins UP-TO-DATE
> Task :buildSrc:check SKIPPED
> Task :buildSrc:build UP-TO-DATE
Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.
You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
BUILD SUCCESSFUL in 13m 13s
7 actionable tasks: 7 up-to-date
A build scan was not published as you have not authenticated with server 'ge.spring.io'.
For more information, please see https://gradle.com/help/gradle-authenticating-with-gradle-enterprise.
Build scan background action failed.
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)
BUILD SUCCESSFUL in 2m 7s
仔细观察上方报错信息,会发现这是一个关于Git的错误提示信息,下面开始解决。
2.3、解决Git报错信息
1、下载一个终端软件客户端:GitBash,如果已有则忽略该条,如下图:
2、在Spring源码项目根路径下打开终端执行以下命令:
# git init . 注意:该命令后有一个空格 + 点,该条命令为初始化仓库
# git add . 注意:该命令后有一个空格 + 点,该条命令将Spring源码项目添加到Git缓冲区中
# git commit -am 'Commit message' 注意:该条命令将Git缓冲区中的项目进行提交至Git中,并编写提交项目信息。
提交完毕后,回到项目中,重新刷新一下项目,或者build。刷新完毕后控制台信息在下方,这时完美解决Git错误信息,详情日志如下图,无报错信息,完美解决:
> Task :buildSrc:compileJava UP-TO-DATE
> Task :buildSrc:compileGroovy NO-SOURCE
> Task :buildSrc:pluginDescriptors UP-TO-DATE
> Task :buildSrc:processResources UP-TO-DATE
> Task :buildSrc:classes UP-TO-DATE
> Task :buildSrc:jar UP-TO-DATE
> Task :buildSrc:generateSourceRoots UP-TO-DATE
> Task :buildSrc:assemble UP-TO-DATE
> Task :buildSrc:pluginUnderTestMetadata UP-TO-DATE
> Task :buildSrc:compileTestJava NO-SOURCE
> Task :buildSrc:compileTestGroovy NO-SOURCE
> Task :buildSrc:processTestResources NO-SOURCE
> Task :buildSrc:testClasses UP-TO-DATE
> Task :buildSrc:test SKIPPED
> Task :buildSrc:validatePlugins UP-TO-DATE
> Task :buildSrc:check SKIPPED
> Task :buildSrc:build UP-TO-DATE
Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.
You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
BUILD SUCCESSFUL in 1m 5s
7 actionable tasks: 7 up-to-date
A build scan was not published as you have not authenticated with server 'ge.spring.io'.
For more information, please see https://gradle.com/help/gradle-authenticating-with-gradle-enterprise.
BUILD SUCCESSFUL in 1s
三、编译Spring核心模块
- 点击IDEA右侧的Gradle工具栏,编译spring-oxm模块。
- spring-oxm——> Tasks ——> other ——> 双击:compileTestJava
- 控制台出现以下内容代表成功:BUILD SUCCESSFUL in 3m 39s
- 点击IDEA右侧的Gradle工具栏,编译spring-core模块。
- spring-core——> Tasks ——> other ——> 双击:compileTestJava
- 控制台出现以下内容代表成功:BUILD SUCCESSFUL in 41s
- 以上核心模块编译完成后,点击IDEA右侧的Gradle工具栏,开始编译整个项目工程,这里比较耗费时间。
- spring ——> Tasks ——> build ——> 双击:build
四、创建模块验证项目是否可运行
模块名称必须以spring-
开头,否则依赖注入不到模块中:
项目创建完毕之后,默认的gradle文件是:build.gradle文件,这里导入依赖:
//下方注入依赖,需要学习什么源码,就添加什么依赖
dependencies {
optional(project(":spring-context"))
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
}
在刚刚创建的模块中新增spring配置文件:
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="teacher" class="com.xiaowu.bean.Teacher">
<property name="name" value="zhangsan"/>
</bean>
</beans>
创建实体类,Teacher :
package com.xiaowu.springioc.bean;
/**
* @author zhangXiaoPeng
* @date 2023年07月01日 23:44
*/
public class Teacher {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
'}';
}
}
创建main方法,进行测试,验证Spring源码项目是否可执行:
package com.xiaowu.mains;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author zhangXiaoPeng
* @date 2023年07月01日 23:45
*/
public class MySpringIOC {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Object teacher = context.getBean("teacher");
System.out.println(teacher.toString());
}
}
项目完美运行,下方效果图: