IDEA 导入 spring 源码

文章目录

  • 前言
  • 一、下载源码
  • 二、安装 Gradle
    • 1. 下载 Gradle
    • 2. 配置环境变量
  • 三、导入前准备
  • 四、编译源码
    • 1. 导入源码
    • 2. 我所遇见的问题
  • 五、测试
    • 1. 创建 module
    • 2. 编写测试代码
    • 3. 我所遇到的问题
  • 六、总结


前言

我们在学习 spring 源码的时候,有时候是需要在阅读源码的时候添加一些代码注释,或者是对源码的一些感悟,如果没有将 spring 的源码导入到 IDEA 中,单纯是通过 Maven 去阅读 jar 的形式是无法添加一些注释信息的,即便可以通过一些比如像 Private Notes 这样的插件做到在源代码中添加注释,但还是有局限性的,首先这个插件不允许你更改源码的行数,所以你的私人注释只能写在一行里,其次导入源代码,你可以更改源代码比如说打印一些东西,都是更有助于去理解源码的。

以下内容是我第一次使用 IDEA 去导入 Spring 源码的一个过程,踩了很多坑,我也记录下我所遇见的问题,以及解决的方案,希望对你有所帮助。


spring 官网:https://spring.io/

一、下载源码

我们可以在 github 或者 gitee 上都能下载到 spring 的源码

github 上下载:

github 上搜索 spring-fremawork 就能找到:https://github.com/spring-projects/spring-framework

在这里插入图片描述

gitee 上下载:

gitee 上搜索 spring-fremawork 就能找到:https://gitee.com/mirrors/spring-framework?_from=gitee_search

在这里插入图片描述

虽然说使用可以 git clone 下载源码,但是不太推荐(本人亲自踩过坑,好多问题),这里最好还是直接下载 ZIP 压缩包

我在电脑上创建了 /source-code 这样一个文件夹用于管理我的源代码,然后将下载好的源代码解压缩到该文件夹下,这里我学习的版本是 spring-framework-5.2.x

在这里插入图片描述


二、安装 Gradle


1. 下载 Gradle

Gradle 是一个构建工具,它类似于 Meven,Spring 就是用 Gradle 进行编译的,所以我们还是下载个 Gradle 会比较好。
在这里插入图片描述

下载 Gradle 我们一定要找到跟你下载的 Spring 源码兼容的版本,在你下载好的源码中的 \spring-framework-5.2.x\gradle\wrapper\gradle-wrapper.properties 文件中可以查找到应该下载哪个版本的 Gradle

在这里插入图片描述

所以按照 gradle-wrapper.properties 文件的指定我应该下载 gradle-5.6.4-bin.zip 这个版本的 Gradle

去到官网上下载 https://services.gradle.org/distributions/

在这里插入图片描述

我创建了一个 /gradle 的文件夹存放刚刚下载好的 Gradle,再进行解压

Gradle 和 Meven 一样都有个仓库,这里为了方便,我把 Gradle 的仓库 .gradle 也创建在这个目录下了

在这里插入图片描述


2. 配置环境变量

鼠标右键 我的电脑(此电脑) - 属性 - 高级系统设置 再选择 环境变量

添加链接描述

点击 环境变量 进来大概是这样子的,点击 新建

添加链接描述

如下图所示进行配置,配置完成后,点击确定保存配置

配置 GRADLE_HOME

变量名:GRADLE_HOME
变量值:D:\gradle\gradle-5.6.4-bin\gradle-5.6.4(Gradle 的安装目录,也就是 bin 文件夹所在的目录)

在这里插入图片描述

配置 GRADLE_USER_HOME

变量名:GRADLE_USER_HOME
变量值:D:\gradle\.gradle(Gradle 仓库目录)

在这里插入图片描述

同时还需要添加 Path 的 配置,选择 Path ,点击 编辑

添加链接描述

新建环境变量:

  • %GRADLE_HOME%\bin
  • %GRADLE_USER_HOME%

在这里插入图片描述

确定 保存

现在 cmd 打开命令窗口,输入 gradle -v 命令检测 Gradle 是否安装成功

在这里插入图片描述

能够看到 版本信息 就 ok 了


三、导入前准备

为了加速 gradle 下载依赖包的速度,我们需要在 build.gradlesettings.gradle 这两个文件中添加国内的镜像地址。

在这里插入图片描述

build.gradle 文件

在这里插入图片描述

maven { url "https://maven.aliyun.com/nexus/content/groups/public/"}
maven { url "https://maven.aliyun.com/nexus/content/repositories/jcenter"}
maven { url "https://repo.springsource.org/plugins-release"}

settings.gradle 文件

在这里插入图片描述

maven{ url "https://maven.aliyun.com/nexus/content/groups/public/"}

spring-framework\gradle\wrapper\gradle-wrapper.properties 文件中的 distributionUrl 修改成自己下载的 (PS:这一步可做可不做

在这里插入图片描述

distributionUrl=file\:///D\:/gradle/gradle-5.6.4-bin.zip

四、编译源码


1. 导入源码

打开 IDEA ,选择 File -> Open

在这里插入图片描述

选中 spring 源码所在目录

在这里插入图片描述

导入进来是这样子的

在这里插入图片描述

项目导进来之后先检查下 JDK 的配置,因为 Gradle JVM 是需要使用 JDK 11,所以务必配置 JDK 11,可以避免很多坑

在这里插入图片描述

在这里插入图片描述

然后再配置 Gradle

在这里插入图片描述

检查下 git 配置(编译的时候会自动去检测 git,所以需要检查下)

在这里插入图片描述

接下来就等项目自动构建,因为这个过程 Gradle 会下载一些 jar 包需要一些时间。

在这里插入图片描述

当你看到每一个项目 右下角 基本上都带着一个 蓝色方块,就表示 Spring 的源码导入成功了。

如果你在上述过程中遇到问题,不妨往下面看看 ~~


2. 我所遇见的问题

  1. fatal: not a git repository (or any of the parent directories): .git

在这里插入图片描述

解决这个问题很简单,进到这层目录下, 调起 Git Bash Here ,依次执行以下三行命令

git init
git add .
git commit -m "随便写点啥都行"

在这里插入图片描述

在去 IDEA 中重新构建一下就好了

  1. Gradle 版本导致 A problem occurred evaluating root project 'spring'. 等问题

在这里插入图片描述

之前我是按照 gradle.properties 这个文件下载的 gradle-5.3-bin.zip,我以为够了,没想到 java-test-fixtures 这些包下载不到,没办法,我只能根据 gradle-wrapper.properties 再下载一个 gradle-5.6.4-bin.zip 的版本

在这里插入图片描述

重新设置一下 IDEA 的 GreadleSpecified location,选择刚下的 Gradle gradle-5.6.4-bin.zip 的版本

在这里插入图片描述

所以还是要以 gradle-wrapper.properties 文件指定的 Gradle 版本为准会避免掉一些坑

  1. POM relocation to an other version number is not fully supported in Gradle : xml-apis:xml-apis:2.0.2 relocated to xml-apis:xml-apis:1.0.b2

在这里插入图片描述

我重新构建下就好了,所以也没啥好说的


五、测试


1. 创建 module

现在源码是顺利的导入进来了,那就在 spring 的项目中新建一个 module 来测试一下

右键项目根目录,New -> Module 创建一个 module

在这里插入图片描述

这个要选 Gradle,点击 Next

在这里插入图片描述

设置模块名,点击 Finish

在这里插入图片描述

就 ok 了

在这里插入图片描述


2. 编写测试代码

在这里插入图片描述

替换成

在这里插入图片描述

    testImplementation group: 'junit', name: 'junit', version: '4.13.1'
    testImplementation group: 'org.hamcrest', name: 'hamcrest-core', version: '1.3'
    compile(project(":spring-context"))

这里简单说明以下,Gradle 如果引用的是本项目中的模块,则使用 compile(project(":moduleName)),如果使用的是第三方的包,则使用 testImplementation group:xxxx ' 导入

测试结果:

可以看到是没什么问题的,没有报错,并且使用的类是本项目的,能够正确执行

在这里插入图片描述

测试代码如下:

UserController.calss

package com.mike.controller;

import com.mike.service.UserService;

public class UserController {

	private UserService userService;

	/**
	 * DI:set 方法注入
	 */
	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	public String findAll() {
		return userService.findAll();
	}
}

UserService.java

package com.mike.service;

public interface UserService {

	String findAll();

}

UserServiceImpl.java

package com.mike.service.impl;

import com.mike.service.UserService;

public class UserServiceImpl implements UserService {

	@Override
	public String findAll() {
		return "返回所有用户信息";
	}

}

MainTest.java

package com.mike.test;

import com.mike.controller.UserController;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainTest {

	@Test
	public void test() {
		// 获取 Spring 容器对象
		// 执行这行代码相当于启动了 Spring 容器,解析 spring.xml 文件,并且实例化所有的 bean 对象放到 spring 容器中
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring.xml");
		// 获取 UserController 对象
		UserController userController = applicationContext.getBean("userController", UserController.class);
		// 执行方法
		String allUsers = userController.findAll();
		System.out.println("allUsers = " + allUsers);
	}
}

spring.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 http://www.springframework.org/schema/beans/spring-beans.xsd">


	<!-- 使用 Spring IOC 和 ID 管理对象 -->
	<bean id="userService" class="com.mike.service.impl.UserServiceImpl"/>

	<bean id="userController" class="com.mike.controller.UserController">
		<property name="userService" ref="userService"/>
	</bean>

</beans>

如果你在上述过程中遇到问题,不妨往下面看看 ~~


3. 我所遇到的问题

  1. build.gradle 怎么配置第三方依赖

比如我写的测试模板中需要 junit,在 pom 文件中我们可以这样导入

        <!-- junit 单元测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.1</version>
            <scope>test</scope>
        </dependency>

但是在 build.gradle 文件中我们该怎么去写呢?

其实在 Maven 仓库 中就提供了 Gradle 的导入方式,直接复制过来就行了

在这里插入图片描述

  1. Kotlin: warnings found and -Weeror specified

在我写完测试代码之后运行 MainTest 类中的 test() 方法所报

在这里插入图片描述

这个问题出现的原因是 缺少 cglib 和 objenesis 包

解决:在这个目录下调起命令行窗口

在这里插入图片描述

输入以下两个指令:

gradle objenesisRepackJar
gradle cglibRepackJar

在这里插入图片描述

  1. java: 找不到符 符号:变量 CoroutinesUtils

解决上一个问题之后再运行 MainTest 类中的 test() 方法所报,这个问题可以说经常会遇到,每构建一次项目都有可能出现

在这里插入图片描述

这是因为 CoroutinesUtilskotlin 的一个工具类,Spring 源码包读取不到,所以需要手动添加 kotlin-coroutines-X.X.X.BUILD-SNAPSHOT.jarLibraries 中。

点击 File -> Project Structure -> Libraries -> + -> Java

在这里插入图片描述

然后选择 spring-framework/spring-core/kotlin-coroutines/build/libs/kotlin-coroutines-X.X.X.BUILD-SNAPSHOT.jar 点击 OK (如果你的 kotlin-coroutines 目录下没有 build 目录,跳转到问题3)

在这里插入图片描述

然后就会跳出一个选择 modules 的页面,选中 spring.spring-core.main 点击 OK

在这里插入图片描述

  1. kotlin-coroutines 目录下没有 build 目录

如果你和我一样并没有发现

在这里插入图片描述

点击右侧的 Gradle -> Tasks -> other -> complieKotlin

在这里插入图片描述

编译之后就有了

  1. compileXXXX 时或者在运行时报错 PropertyComparator<capture#1, 共 ?>无法转换为java.util.Comparator<? super capture#1, 共 ?> 等各种泛型使用问题

比如 compileKontlin 时

D:\source-code\spring-framework-5.2.x\spring-framework-5.2.x\spring-beans\src\main\java\org\springframework\beans\support\PropertyComparator.java:138: ����: �����ݵ�����: PropertyComparator<CAP#1>�޷�ת��ΪComparator<? super CAP#1>
			source.sort(new PropertyComparator<>(sortDefinition));
			            ^
  ����, CAP#1�������ͱ���:
    CAP#1��?�IJ�����չObject

在这里插入图片描述

或者是运行 main 方法、Test 方法 时

D:\source-code\spring-framework-5.2.x\spring-framework-5.2.x\spring-beans\src\main\java\org\springframework\beans\support\PropertyComparator.java:138:25
java: 不兼容的类型: org.springframework.beans.support.PropertyComparator<capture#1,?>无法转换为java.util.Comparator<? super capture#1,?>

在这里插入图片描述

这个问题感觉是跟泛型有关的坑,我就改了下源码

在这里插入图片描述

再编译之后这个问题就没有再出现了,不过又出现新的问题

D:\source-code\spring-framework-5.2.x\spring-framework-5.2.x\spring-messaging\src\main\java\org\springframework\messaging\handler\annotation\reactive\PayloadMethodArgumentResolver.java:236: ����: �����ݵ�����: lambda ���ʽ�еķ������ʹ���
							.onErrorResume(ex -> Flux.error(handleReadError(parameter, message, ex)));
							                               ^
    Flux<CAP#1>�޷�ת��ΪPublisher<? extends CAP#1>
  ����, CAP#1�������ͱ���:
    CAP#1��?�IJ�����չObject

在这里插入图片描述

也跟泛型有关,所以修改这边的代码不是个很好的解决办法,改了一个后续还会遇见很多个,治标不治本

这个问题出现的原因是 gradle jvm 的版本没有使用 jdk 11导致的,所以 Gradle JVM 务必换成 JDK 11

在这里插入图片描述

Project 的 JDK 也改成 11

在这里插入图片描述

再编译就没问题了

在这里插入图片描述


六、总结

以上就是我使用 IDEA 导入 Spring 源码的全过程,不得不说 IDEA 导入 Spring 源码真的有好多的坑啊,不知道多少学习源码的人在这里就被劝退了 ~~

其中还有些错误我没有列举出来,因为这是我优化过后总结出来的,所以另外些错误我没有再遇到过就不写在这上面了,在这个过程中觉得最大的阻碍就是对 Gradle 的不熟悉,很多问题都跟 Gradle 有关,好在最后都解决了,也希望这篇文章能够让你在学习源码的过程中有个好的开头。


参考博客:
《Spring》第一篇 IDEA导入Spring源码:https://blog.csdn.net/weixin_44167408/article/details/121769949
知乎:spring源码编译的过程和问题:https://zhuanlan.zhihu.com/p/378831634

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/20050.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HS6621系列低功耗国产蓝牙芯片 支持蓝牙5.1

HS6621CxC是一个功耗优化的蓝牙低功耗和专有的2.4 ghz应用真正的芯片上系统(SOC)解决方案。它集成了一个具有蓝牙基带和丰富外设的低功耗射频收发器I0扩展。HS6621CxC还集成了电源管理&#xff0c;提供高效率电源管理。它的目标是2.4 G蓝牙低功耗系统&#xff0c;人机界面设备(…

File类、IO数据流介绍

文章目录 &#x1f412;个人主页&#x1f3c5;JavaSE系列专栏&#x1f4d6;前言&#xff1a;&#x1f380;File类的设计&#x1fa85;数据流的流向 &#x1f3c5;对数据操作的类&#x1f9f8;按单位划分&#x1f9f8;按封装类型划分 &#x1f380;整理File常用方法 &#x1f41…

有赞一面:亿级用户DAU日活统计,有几种方案?

说在前面 在40岁老架构师 尼恩的读者社区(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如极兔、有赞、希音、百度、网易、滴滴的面试资格&#xff0c;遇到一几个很重要的面试题&#xff1a; (1) 亿级用户场景&#xff0c;如何高性能统计日活&#xff1f; (2) 如何实现亿…

智见|中国能建中电工程罗必雄:数能融合为数字中国夯实底座

出品|网易科技《智见访谈》 作者&#xff5c;赵芙瑶 编辑&#xff5c;丁广胜 数字化浪潮的风&#xff0c;吹到了能源结构转型领域。 中国作为全球最大的能源生产国和消费国&#xff0c;正积极推动能源行业的数字化和智能化建设。数字化智能化升级在能源产业中被视为一项重要的战…

lambda处理异常四种方式

最近对接第三方呼叫系统&#xff0c;第三方SDK的所有方法里都有异常抛出&#xff0c;因为用到了lambda&#xff0c;所以异常处理还是很必要的。 本文主要用到了四种解决方案&#xff1a; 直接代码块处理自定义函数式接口&#xff0c;warp静态方法通过Either 类型包装通过Pair 类…

【Android】Exam5 ListView组件简单应用

Exam5 ListView组件简单应用 ListView组件简单应用 Exam5 ListView组件简单应用目的实验内容及实验步骤采用SimpleAdapter自定义Adapter运行及结果&#xff1a;实验总结 目的 掌握常用的UI布局及组件&#xff1b; 掌握使用Intent启动Activity的方法 掌握ListView组件的简单应用…

[离散数学] 函数

文章目录 函数判断函数的条件复合函数复合函数的性质 逆函数 函数 判断函数的条件 dom F A ⇔ \Leftrightarrow ⇔所有x 都有 F&#xff08;x&#xff09;与之对应 有唯一的与其对应 < x , y > ∈ f ∧ < y , z > ∈ f ⇒ y z <x,y>\in f \land <y,z…

无需繁琐手工操作,如何利用Web自动化测试元素定位做到快速高效的测试?

1、什么是Web自动化测试元素定位&#xff1f; 在Web自动化测试中&#xff0c;元素定位是非常重要的环节。因为我们需要找到需要进行操作的页面元素&#xff0c;例如按钮、输入框、下拉菜单等等。元素定位可以帮助我们在自动化测试中对这些元素进行操作&#xff0c;如点击、输入…

生物识别技术能否成为应对安全挑战的绝佳选择?

生物识别技术能否成为应对安全挑战的绝佳选择&#xff1f; 生物识别技术是利用人体固有的生理特征或行为特征来进行身份鉴别的一种技术&#xff0c;如指纹、人脸、声纹、虹膜等。1 生物识别技术具有不可撤销性、高度便利性和较低错误率等优势&#xff0c;在安全领域中也备受瞩目…

React动态路由配置

目录 项目初始化 模块创建 统一导出 全局模块配置选项 核心代码 使用及效果展示 博文适用于react-router v6及以上&#xff0c;其中还有很多值得改进的地方 最近学习react的过程中&#xff0c;思考怎样实现动态路由的配置(最终实现从页面配置最终动态从数据库加载上线模…

Stable Diffusion webui安装使用

参考&#xff1a; https://stability.ai/blog/stable-diffusion-public-release https://github.com/AUTOMATIC1111/stable-diffusion-webui 1、安装&#xff08;6g显存&#xff09; 1、conda创建python 3.10.6环境 conda create -n stable-diffusion pythonpython 3.10.6 也安…

中国南方Oracle用户组沙龙活动:大环境下的Oracle数据库的机遇与挑战

2023年03月12日(周日)在杭州索菲特西湖大酒店 (浙江省杭州市上城区西湖大道333 号)&#xff0c;中国南方Oracle用户组创始人之一&#xff1a;周亮&#xff08;zhou liang&#xff09;组织举办了主题为《大环境下的Oracle数据库的机遇与挑战》活动&#xff0c;大约有50名左右的人…

刷完这个笔记,17K不能再少了....

大家好&#xff0c;最近有不少小伙伴在后台留言&#xff0c;得准备面试了&#xff0c;又不知道从何下手&#xff01;为了帮大家节约时间&#xff0c;特意准备了一份面试相关的资料&#xff0c;内容非常的全面&#xff0c;真的可以好好补一补&#xff0c;希望大家在都能拿到理想…

马赛克处理

去取马赛克的网址&#xff1a; Redact • Photo - Free And Private Image Redaction In The Browser https://redact.photo/ REDACT.PHOTO &#xff08;照片马赛克处理在线工具&#xff09;简介 REDACT.PHOTO是一个照片马赛克处理在线工具&#xff0c;能够帮助我们非常方便…

ChatGPT使用体验

ChatGPT使用体验 前言 介绍ChatGPT 体验ChatGPT 菜谱 编程学习 出行导航 导游攻略 中英翻译 电影推荐 文章总结 总结 前言 最近关于ChatGPT的话题已经火爆了&#xff0c;我也观察和体验了一段时间。平心而论&#xff0c;这东西真的黑科技&#xff0c;大多行业都能通…

Windows10安装二进制Mysql-5.7.41和汉化

1.创建my.ini [mysqld] ##skip-grant-tables1 port 3306 basedirD:/webStudy/mysql-5.7.41 datadirE:/adata/mysqlData max_connections200 character-set-serverutf8 default-storage-engineINNODB sql_modeNO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES [mysql] default-char…

论文解读|MetaAI图像分割基础模型SAM——解锁数字大脑“视觉区”

原创 | 文 BFT机器人 内容提要 事件背景: 2023年4月5日&#xff0c;MetaAI研究团队发布论文“分割一切”一《Segment Anything》并在官网发布了图像分割基础模型一Segment Anything Model(SAM)以及图像注释数据集Segment-Anything 1-Billion(SA-1B)。 论文核心观点 : 目…

Simulink 和 Gazebo联合仿真控制机械臂【Matlab R2022a】

逛 B 站&#xff0c;偶然发现一个 up 主上传的视频&#xff0c;可以实现 Simulink 中搭建机器人的控制器设计&#xff0c;对运行在虚拟机中 Gazebo 中的机械臂进行控制&#xff0c;链接&#xff1a;三关节机械臂Gazebo-Simulink联合仿真&#xff0c;这让我很感兴趣&#xff0c;…

60岁的机器视觉工程师,你还在敲代码?不想做机器视觉工程师,还可以做什么?机器视觉工程师职业生命线有多长​?

如果按程序员参加工作时间为22岁计算,平均退役年龄为35岁计算的话,程序员的职业寿命大概为14年。为什么程序员的职业生命线如此短暂呢?大致有以下几点—— 1、编程技术层出不穷,迭代速度非常快,这时候就需要我们不断的学习,不断地保持学习能力,当随着年龄的增长我们的学…

K8S系列之污点和容忍度详细分析

架构图 本篇文档主要介绍污点和容忍度的关系。 污点和容忍度 污点顾名思义就是脏的东西&#xff0c;给节点添加污点来限制pod调度到该节点上&#xff0c;如果pod可以容忍这种污点就可以被调度到有污点的节点上&#xff0c;如果不能容忍就不能被调度到该节点上。 污点作用于节…