六. 测试案例
在完成上文 Spring 源码编译之后,Congratulations ! 接下来新增一个示例模块来依赖工程中的其它 spring 模块做个简单的测试。
1. 新增模块
File → Module 新增 spring-sample 示例模块
2. 添加依赖
在 spring-sample 模块下的 build.gradle 新增 spring-context 依赖,它是包含了 spring-core、 spring-bean 和 IoC容器等Spring 运行时上下文的依赖。
api(project(":spring-context"))
1
3. 测试代码
代码结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aJlv6qAe-1670807292651)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0619225e2eaa4e599fb00f3ab498cba3~tplv-k3u1fbpfcp-zoom-1.image)]
/**
* 人接口
*/
public interface IPersonService {
/**
* 说
*/
void speak();
}
/**
* 中国人
*/
@Service
@Primary
public class ChineseService implements IPersonService {
@Override
public void speak() {
System.out.println("我会说中文");
}
}
/**
* 美国人
*/
@Service
public class AmericanService implements IPersonService {
@Override
public void speak() {
System.out.println("I can speak English");
}
}
/**
* 启动测试类
*/
@ComponentScan("com.youlai.spring.sample.**")
public class SpringSampleApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
SpringSampleApplication.class
);
IPersonService personService = context.getBean(IPersonService.class);
personService.speak();
}
}
4. 测试结果
image-20221210232239371
七. 源码阅读
本章节就基于编译好的 Spring 源码环境进行源码调试,为了方便下面就基于上章节的测试案例来对 getBean 源码流程分析,后续会更新出 Spring 源码阅读系列文章。
1. getBean 源码
快速定位: 通过 Debug (F7)可以很清晰看到详细的调用栈
image-20221210230131704
加深理解记忆: 基于调用栈绘制时序图(IDEA的PlantUML插件)
时序图源文件:https://gitee.com/youlaiorg/spring-framework/blob/master/doc/diagram/getBean.puml
getBean时序图
深入概念原理
时序图反映了在getBean()调用链中 DefaultListableBeanFactory 承担着核心角色,甚至可以说是 Spring 最核心的一个 BeanFacory 实现 ,也被称为 Spring 的 “发动机”,所以其重要性是学习 Spring 源码的必修课。
DefaultListableBeanFactory : 可枚举的Bean工厂。
通过类注释我们可以了解到:DefaultListableBeanFactory 是一个成熟的bean工厂;包含了 bean 定义元数据(beanDefinitionMap),提供了Bean定义的注册和获取方法;管理已存在的Bean实例,而不是基于Bean定义去创建新实例。
2. todo
后续更新 Spring 6 源码阅读系列 @有来技术。
八. 问题整理
在编译过程中,因环境不同每个人可能遇到的问题也都不同,但是总结出来的都是没按照官方文档要求或者自己粗心所致,下面就总结编译中遇到常见的问题,也希望大家在留言区把自己遇到问题记录下。
1. 问题一
报错详情
D:\SourceCode\spring-framework>gradlew :spring-oxm:compileTestJava
> Task :buildSrc:compileJava FAILED
D:\SourceCode\spring-framework\buildSrc\src\main\java\org\springframework\build\KotlinConventions.java:44: 错误: 找不到符号
freeCompilerArgs.addAll(List.of("-Xsuppress-version-warnings", "-Xjsr305=strict", "-opt-in=kotlin.RequiresOptIn"));
^
符号: 方法 of(java.lang.String,java.lang.String,java.lang.String)
位置: 接口 java.util.List
1 个错误
FAILURE: Build failed with an exception.
解决方案
gradlew :spring-oxm:compileTestJava info 查看使用 JDK 的版本是不是17,如果不是请在配置文件 gradle.properties 添加:
org.gradle.java.home=D:\Java\jdk-17.0.3.1
1
2. todo
欢迎大家留言区补充或提问~
九. 结语
本篇从 Spring 6 编译依赖的基础环境搭建(JDK17和Gradle)开始、根据官方文档编译源码、在工程新增示例模块测试、以及最后通过对getBean的源码调试,绘制时序图和类注释辅助手段来掌握高效阅读Spring源码技巧。还有一点需要提醒,一定要带着一个明确的目的去看源码,不要被动式的为了学习而学习,不然很容易在知识的海洋里呛水。最后预祝大家编译成功,掌握到属于自己高效阅读源码的方式。
持续更新~
附. 源码
Spring 6 编译源码仓库地址: https://gitee.com/youlaiorg/spring-framework