Spring Data JPA内部原理解析

喜你入骨 提交于 2019-12-17 23:03:15

Spring Data JPA常用接口分析

在入门案例中,我们仅仅定义了CustomerDao的接口,并没有提供任何的方法,那么我们所调用的增删改查的方法来自哪里呢?答案很简单,对于我们自定义的Dao接口,由于继承了JpaRepository和JpaSpecificationExecutor,所以我们可以使用这两个接口的所有方法。

进入JpaRepository,在类上按住ctrl+F2:

JpaRepository的方法

在JpaSpecificationExecutor中也是类似的情况。

但是我们注意到,JpaRepository和JpaSpecificationExecutor是接口,其只是一些方法声明,没有具体的实现方式,那么在 Spring Data JPA中它又是怎么实现的呢?

Spring Data JPA的实现过程

已根据id查询用户代码为例:

打断点,观察我们定义的customerdao的实现对象是谁:

debug查询用户案例
我们可以看到产生了一个动态代理对象JdkDynamicAopProxy,而该对象是Spring内部通过AOP帮助我们创建对象的,单机右键,查看源码:

查看JdkDynamicAopProxy对象源码

进如到JdkDynamicAopProxy对象中:

JdkDynamicAopProxy对象

我们发现JdkDynamicAopProxy对象实现了InvocationHandler接口,找到invoke方法,其中target对象就是生成的动态代理对象,打断点查看:

target对象就是生成的动态代理对象

让我们查询一下target对象的源代码(其实是SimpleJpaRepository对象)

SimpleJpaRepository源码

可以看到SimpleJpaRepository对象继承实现了JpaRepository和JpaSpecificationExecutor接口中的方法。

SimpleJpaRepository源码

SimpleJpaRepository所实现的方法

由于我们的测试案例是根据用户id查询用户,实际上调用了findOne()方法,那么究竟是不是调用了SimpleJpaRepository对象中的findOne()方法呢?我们打断点测试一下:

findOne(Integer)

我们可以看到,页面跳转到SimpleJpaRepository对象中的findOne()方法中,且接收到参数为1,与测试案例相吻合。

顺带一提,上述findOne()方法返回了一个em.find(),其实em就是EntityManager对象,而他是JPA原生的实现方式,所以我们得到结论Spring Data JPA只是对标准JPA操作进行了进一步封装,简化了Dao层代码的开发。

Spring Data JPA完整调用过程分析

在这里插入图片描述

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!