Spring Data JPA内部原理解析

本文深入解析SpringDataJPA的工作原理,包括其如何通过动态代理实现接口方法,以及SimpleJpaRepository在查询过程中的作用。揭示了SpringDataJPA对JPA标准操作的封装与简化。

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完整调用过程分析

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值