目录
前言
工欲善其事必先利其器. 学习和深读 Spring 源码一个重要的前提: 编译源码到我们的本地环境. 这样方便我们在本地环境添加注释, 断点追踪, 查看类或接口的继承关系等等, 更加高效的学习 Spring 源码. 个人觉得深读 Spring 源码对我们的编码水平会有很大很大的提升, 因为其牵涉的广度, 深读, 以及优秀编码规范都值得我们去品, 细品, 慢慢品. 废话不多说, 本篇就如何在我们的 intelliJ IDEA 编译 Spring 源码的步骤以及在编译的过程中遇到的问题做一个详细说明.
环境
开发工具: IntelliJ IDEA 20193.3
编译工具: gradle-6.4-rc-4
操作系统: Windows 10
编译
一, 下载 Spring 源码
访问 Spring 官方源码地址 , 下载源码 zip 包到本地
二, 下载和配置编译工具 Gradle
1. 下载 Gradle
访问 Gradle 官网 https://services.gradle.org/distributions/ , 选择 gradle-6.4-rc-4-bin.zip(截止 2020-05-03 当前最新), 下载到本地并解压
2. 配置 Gradle 系统环境变量
3. 验证 Gradle
三, IntelliJ IDEA 编译 Spring 源码
1. 导入 Spring 源码至 IntelliJ IDEA
将之前下载好的 Spring 源码解压后导入到 IDEA, 依次点击 File->New->Project from Existing Sources, 选择源码包路径下的 build.gradle 文件完成源码导入
2. IntelliJ IDEA 配置 Gradle
依次打开 File->Settings
3. 开始编译
在编译开始之前, 我们先看看下载的官方源码里给出的导入 IDEA 的提示
按照上面描述, 因为上面导入我是按照第二步去做的. 最后仅仅只需做第 1 条, 预编译 spring-oxm. 进入项目路径, 执行以下命令完成 spring-oxm 的预编译即可
gradlew :spring-oxm:compileTestJava
完成了 spring-oxm 的预编译之后, 就可以编译我们的代码了, 一般由 IDEA 自动帮我们完成源码到 projects 的转换, 也可以由我们手动 import.
自此, 编译的整个过程已经完成. 下面我们要做的事就是添加自己的模块对已编译的项目模块进行验证测试, 相信我验证会是一个有趣的过程.
测试
打开源码我们可以看到每个模块都对应的有单元测试, 再相比较平时自己在开发时干的事情. 再想到流行的敏捷开发模式中的 TDD(测试驱动开发), 没有测试就没有功能代码. 不禁觉得其中的优秀是为了让我忘尘而叹.
扯回正题, 不能让你们觉得我扯废话凑字数暴露没啥水平的真实情况. 上面说到各个模块的单元测试我们可以测试编译项目是否有问题, 但是后续学习在于模块之间的整合之上. 所以我在此添加一个新的模块, 这个模块模拟一个 bean 的创建和获取这么个过程.
1. 创建模块 spring-fly4j
如果你们想问这名字有啥深意吗? 抱歉哈.. 没有. 想起 spring-test 起不了, 你们懂 spring 有这个模块了, 起名障碍啊, 强行理解的话:"为了 java 飞吧", 忍住别笑
依次右击项目 ->New->Module
2. 添加测试模块代码
先预览下添加的代码结构吧, 很简单是不? 加上需要添加依赖的 build.gradle 共 5 个文件.
我这里贴出这 5 个文件的代码
- @Configuration
- @ComponentScan("com.fly4j.spring.context.**")
- public class ContextConfig {
- }
- public interface IUserService {
- }
- @Service
- @Scope("singleton")
- public class UserServiceImpl implements IUserService {
- public UserServiceImpl() {
- System.out.println(this.getClass().getSimpleName() + "构造函数执行...");
- }
- }
- public class ContextApplication {
- public static void main(String[] args) {
- AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
- ContextConfig.class
- );
- IUserService bean = context.getBean(IUserService.class);
- System.out.println(bean);
- }
- }
- // build.gradle
- dependencies {
- testCompile group: 'junit', name: 'junit', version: '4.12'
- compile(project(":spring-context"))
- compile(project(":spring-instrument"))
- }
相信以上代码机智的你一看就明白其意, 其中 build.gradle 就只添加了 spring-context 和 spring-instrument 的依赖, spring-context 模块里包含了 bean 工厂, 可想而知, 我这里生成 bean 和取出 bean 的测试案例是多么的依赖这个模块, 另一个 spring-instrument 是 spring-context 模块编译需要的.
3. 测试
运行 ContextApplication 的 main 方法, 其中会提示找不到 CoroutinesUtils 符号, 这个问题解决我在下面一节的 "问题一" 进行了说明, 我这里先放结果好了.
如上可以看到从上下文注入 bean 和取出 bean 的过程, 至此 spring-context 这个重要模块验证成功结束.
问题
1. 问题一
Error:(350, 51) java: 找不到符号
符号: 变量 CoroutinesUtils
位置: 类 org.springframework.core.ReactiveAdapterRegistry.CoroutinesRegistrar
解决: 依次 File->Project Structure->Libraries->+->java->spring-core->kotlin-coroutines->build->libs->kotlin-coroutines-5.3.0-SNAPSHOT.jar
2. 问题二
Error:(26, 38) java: 找不到符号
符号: 类 InstrumentationSavingAgent
位置: 程序包 org.springframework.instrument
解决: 因为 spring-context 对 spring-instrument 有依赖, 在 build.gradle 添加对 spring-instrument 的依赖即可.
结语
至此, Spring 源码如何在 IntelliJ IDEA 如何编译这篇文章就废话完毕了. 写这篇文章目的我希望把它作为 Spring 系列的开始, 没有环境的学习就像你想抬一个没有边角的桌子无处施力. 如果大家在编译时有什么问题欢迎指出. 也可以联系我 (微信号: WxHXR2015), 大家相互学习, 在当前环境下自己也是一个担心有今天没明天的菜比技术人. 最后贴出我编译好的 spring 源码的地址, 欢迎大家 star. https://github.com/haoxianrui/spring-framework.git
来源: https://www.cnblogs.com/fly4j/p/12825586.html