- 1、源码的官网地址
- 2、选择学习模块
- 3、选择指导介绍那里
- 4、进行构建
- 1、在测试类中打断点,看接口类返回的是啥
- 2、在Spring的refresh方法实例化Bean哪里打断点
- 3、看如何产生代理对象的
- 4、设置过滤条件,方便过滤
- 5、怎么出来了一个工厂Bean(产生两个问题)
- 6、先解决工厂如何来的?
- 7、全局搜索put方法,并打断点
- 8、借助调用栈看哪里产生了FactoryBean
- 9、重新回到最后一个又FactoryBean的反推代码中
- 10、不是目标对象进放过,进入的是目标对象的
- 11、进行新代码如何判断重要的那行代码
- 12、看如何获取FactoryBean的
- 13、到此就是获取一个固定的FactoryBean
- 14、直接全局搜索SimpleJpaRepository
- 15、重新debug进来,结合调用栈进行反推
- 16、继续往下走
- 17、发现代理工厂
- 18、进去看看怎么获取的
- 19、如果获取代理的
- 20、
- 21、时序图(待画)
1、源码的官网地址
https://spring.io/projects/spring-data-jpa
2、选择学习模块
3、选择指导介绍那里
4、进行构建
在弹出对话框中,确保在完整文件夹下选择Maven的pom.xml或Gradle的build.gradle文件
开发Dao接口(ResumeDao),接口的实现对象肯定是通过动态代理来完成的(增强),代理对象 的产生过程追源码很难追,特别特别讲究技巧
源码剖析的主要的过程,就是代理对象产生的过程
我们发现resumeDao是一个代理对象,这个代理对象的类型是SimpleJpaRepository
若想晓得SpringDataJPA如何调用目标方法去执行的。就先得到接口返回的对象,通过接口对象去调用目标方法吧,那么就在接口准备调用目标方法哪里打断点,看返回结果先。
1、在测试类中打断点,看接口类返回的是啥
根据一的情况,那么就产生疑问:这个代理对象是怎么产生,过程怎样? 以往:如果要给一个对象产生代理对象,我们知道是在AbstractApplicationContext的refresh方法中的实例化后,的after方法进行封装的, 那么能不能在这个方法中找到什么我们当前场景的线索?
2、在Spring的refresh方法实例化Bean哪里打断点
打完断点,并debug进去。
3、看如何产生代理对象的
4、设置过滤条件,方便过滤
5、怎么出来了一个工厂Bean(产生两个问题)
根据上面的情况,又出现了两个疑问
问题1:为什么会给它指定为一个JpaRespositoryFactoryBean(getObject方法返回具体的对象)
问题2:指定这个FactoryBean是在什么时候发生的
6、先解决工厂如何来的?
既然FactoryBean是上面得到的,但是它属于遍历的,那就点进去,并设置过滤条件
设置过滤条件,其他断点放开,就debug进入这个断点即可
7、全局搜索put方法,并打断点
打完断点,并设置过滤条件,重新debug进去
8、借助调用栈看哪里产生了FactoryBean
9、重新回到最后一个又FactoryBean的反推代码中
10、不是目标对象进放过,进入的是目标对象的
11、进行新代码如何判断重要的那行代码
12、看如何获取FactoryBean的
13、到此就是获取一个固定的FactoryBean
解决了第5点的问题2,那么继续解决问题1
通过上述追踪我们发现,<jpa:repository basePackage,扫描到的接口,在进行BeanDefintion注册时候,class会被固定的指定为JpaRepositoryFacotryBean 至此,问题2 FactoryBean是在什么时候发生的 追踪完毕
那么接下来,我们再来追踪问题1 JpaRespositoryFactoryBean是一个什么样的类
它是一个FactoryBean,我们重点关注FactoryBean的getObject方法
一路走下来
到这了卡主了,好像没头绪了,那么我就从正面进去,
第一点的时候部署返回SimpleJapRepository对象吗,那么最终都会去调用生成它的,我就全局搜索
找到它,并打断点,然后通过调用栈来往回分析就行了嘛。
14、直接全局搜索SimpleJpaRepository
打完断点,重新debug进去,发现容器初始化的时候就调用了构造方法,这个不可以,那么换一个地方
用下面这种搜索
15、重新debug进来,结合调用栈进行反推
有时间再画时序图
16、继续往下走
17、发现代理工厂
18、进去看看怎么获取的
其实第一次可以先走流程,看获取的结果,第二次再重新debug进去
19、如果获取代理的
先是进入到创建代理这里
得到一个aop代理工厂
20、
由此可见,JdkDynamicAopProxy会⽣成⼀个代理对象类型为SimpleJpaRespository,而该对象的增强 逻辑就在JdkDynamicAopProxy类的invoke方法中至此,问题1追踪完毕。
原来SimpleJpaRepository类实现了JpaRepository接口和JpaSpecificationExecutor接口