前言
本文旨在记录搭建Spring源码环境中遇到的问题和解决方案,以供参考。
1、所需资源
IDEA 2019.1
JDK 1.8
spring-5.2.8.RELEASE
gradle-5.6.4
2、资源下载及版本说明
2.1 spring源码下载
方法一:使用git clone到本地
git clone --branch v5.2.8.RELEASE https://github.com/spring-projects/spring-framework.git
方法二:spring源码直接下载zip文件,下载完成之后放到工作目录解压即可。
ps:为什么要选择RELEASE版本,因为RELEASE版本里使用依赖也都是RELEASE版本的,在maven库中,不会出现找不到的情况。
2.2 gradle下载、安装和配置
2.2.1 gradle下载
1)首先要确定你下载的Spring源码所需要的gradle版本
查看文件:spring-framework/gradle/wrapper/gradle-wrapper.properties
可以确定gradle的版本为:gradle-5.6.4-bin.zip
如果 https://services.gradle.org/distributions/gradle-5.6.4-bin.zip 请求失败,可以修改distributionUrl为本地地址,如下:
#distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip
distributionUrl=file:///D:/work/gradle-5.6.4-bin.zip
gradle版本要一致。如果版本不一致可能会导入spring源码编译失败,很多帖子说的是jdk编译问题,其实是因为没有安装正确版本的gradle,才导致编译出现各种错误。
例如在编译的时候会出现一些函数找不到的情况。
类似错误:Could not find method testCompile() for arguments
2)下载gradle
gradle下载地址:https://services.gradle.org/distributions
下载到本机,并解压到指定路径。
2.2.2 gradle安装
1)gradle-5.6.4-bin.zip 解压到指定路径即完成安装。
2)环境变量配置
新增GRADLE_HOME系统变量,指向gradle的安装路径;
在PATH中配置 %GRADLE_HOME%\bin
打开cmd,输入gradle -v 验证gradle是否安装成功。
3)设置Gradle的本地仓库路径
如果不想gradle下载的文件默认到C盘,可以配置 GRADLE_USER_HOME 系统变量来修改默认仓库路径,自定义gradle_repo文件指定路径。
2.2.3 gradle配置
和maven的settings.xml类似,可以配置gradle的默认配置文件。
在gradle的安装路径下:gradle-5.6.4/init.d/,新增一个文件:init.gradle
init.gradle内容如下:
allprojects {
repositories {
mavenLocal()
maven { url "https://maven.aliyun.com/nexus/content/groups/public/" }
mavenCentral()
}
buildscript {
repositories {
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
}
}
}
3、kotlin版本和调整
4、源码配置调整
4.1 目标文件:build.gradle
1)注释gradle-enterprise-conventions
该plugins加载失败,不注释会导致编译失败。
注释掉这行
//id 'io.spring.gradle-enterprise-conventions' version '0.0.2'
2)为仓库添加上阿里镜像,目的是加快资源下载,加快编译速度。行号约280,在dependencyManagement下的repositories添加:
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
4.2 目标文件:gradle.properties
增加内存,按需加载
1.增加内存分配
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
2.按需配置
org.gradle.configureondemand=true
3.开启守护进程
org.gradle.daemon=true
ps:gradle.properties可以确定spring的version。
5、idea导入spring源码
5.1 导入源码步骤
找到spring-framework源码根目录下的 import-into-idea.md 文件
步骤1:进入spring-framework源码目录,命令 gradlew :spring-oxm:compileTestJava
步骤2:导入idea,File - New - Project from Existing Sources
5.2 预编译,编译测试代码
进入spring源码目录,在此打开cmd,输入 gradlew :spring-oxm:compileTestJava 进行预编译。出现 BUILD SUCCESSFUL 则说明编译成功。
若编译时报错:Execution failed for task ':spring-oxm:compileTestJava'.JiBXException in JiBX
5.3 导入idea
File -> New -> Project from Existing Sources -> Navigate to directory -> Select build.gradle
方法1:直接选择 build.gradle 文件
方法2:直接打开源码项目
进入idea进行设置
内存配置:使用工具编译时,可能会出现内存溢出情况,这里我们编译时需要增加相关参数
-XX:MaxPermSize=2048m -Xmx2048m -XX:MaxHeapSize=2048m
点击 Refresh all Gradle projects
至此spring源码已经导入成功。
6、调试运行
6.1 调试一:创建新的module
module建好之后要先导入spring的源码模块
建立新的测试类,HelloSpring.java:
package spring.demo;
import org.springframework.stereotype.Service;
/**
* HelloService
* @date 2021/9/10 20:16
*/
@Service
public class HelloSpring {
public void say(){
System.out.println("Hello Spring");
}
}
注册HelloSpring类,开始运行:
package spring.demo;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* Unit test for simple App.
*/
public class AppTest
{
/**
* Rigorous Test :-)
*/
@Test
public void test()
{
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.refresh();
context.register(HelloSpring.class);
HelloSpring helloSpring = (HelloSpring) context.getBean("helloSpring");
helloSpring.say();
System.out.println( "执行了 AppTest.test() " );
}
}
maven中需要引入 junit-4.10.jar
1)运行测试类,报错:
需要引入 spring.spring-jcl.main
2)再运行,报错:
需要引入 spring.spring-aop.main
3)再运行,成功。
若再有问题,引入需要的模块,直到运行成功。
OK,最终成功初始化了创建的HelloSpring类。
6.2 调试二:在spring-context模块中创建测试类
1)在spring-context添加测试类,测试验证是否能编译通过。
2)创建测试服务类
package com.chenf.test;
import org.springframework.stereotype.Service;
/**
* HelloWorld
* @date 2021/9/11 0:49
*/
@Service
public class HelloWorld {
public void say() {
System.out.println("Hello World!");
}
}
3)创建配置文件
在test/resources目录下,新建spring-test.xml ,内容如下:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<context:component-scan base-package="com.chenf.test"/>
</beans>
4)创建测试类
在test目录下,新建package:com.chenf.test,新建测试类:HelloWorldTest
package com.chenf.test;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* HelloWorldTest
* @date 2021/9/11 0:50
*/
public class HelloWorldTest {
@Test
public void test() {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-test.xml");
HelloWorld helloWorld = (HelloWorld)applicationContext.getBean("helloWorld");
helloWorld.say();
System.out.println("执行了 HelloWorldTest.test() ");
}
}
5)运行调试
在类HelloWorldTest 方法test() 右击Run,然后等待运行结果。
6)运行结果
运行成功,符合预期。
Hello World!
执行了 HelloWorldTest.test()
BUILD SUCCESSFUL in 3m 39s
50 actionable tasks: 29 executed, 21 up-to-date
0:13:41: Tasks execution finished ':spring-context:cleanTest :spring-context:test --tests "com.chenf.test.HelloWorldTest.test"'.
完结。
参考博客:
Spring源码编译一次性通过&遇到的坑解决方法 - 冰慧 - 博客园
idea导入spring源码并调试运行_ROAOR1的博客-CSDN博客
spring源码阅读环境(几分钟下载包)_lsz-CSDN博客