写了个SpringDataJPA的Demo并Debugger追踪了一下它的源码执行过程,以根据ID查询为例
如下:
我们在使用SpringDataJPA时只用定义接口并继承JpaRepository,JpaSpecificationExecutor这么两个接口,然后就可以实现简单的增删改查功能,看似啥都不用写,其实在调用时源码会通过动态代理帮我们实现这些方法。
/**
* @author LiuK
* @date 2019/1/22 9:28
* @description:
*/
public interface CustomerDao extends JpaRepository<Customer,Long>,JpaSpecificationExecutor<Long> {
}
- 我们调用的是接口中并没有实现的方法方法,在调用时会使用动态代理模式动态生成实现方法。

在Debugger窗口里会发现JdkDynamicAopProxy

- 去查看JdkDynamicAopProxy@4755的原码,实现了InvocationHandler中的invoke增强方法,当执行invoke方法时就会帮我们Dao对象接口生成实现类

- 在invoke实现接口的方法里:Object target就是动态代理对象 我们可以观察到SimpleJpaRepository这个动态代理对象

- 现在去看SimpleJpaRepository的源码;操作:在debugger窗口找到target里的SimpleJpaRepository右键选择Jump To Type Source进入源码

- SimpleJpaRepository源码–>可以发现他与我们自己写的dao接口所继承的接口一致
自己写的接口:
SimpleJpaRepository源码:

- 看SimpleJpaRepository的类结构图可以发现基本增删改查方法都被实现了

- 验证前面定义的findOne()方法:我们可以观察到确实SimpleJpaRepository里的findOne执行了
测试方法:

SimpleJpaRepostory里的findOne:

- SimpleJpaRepostory的findOne方法最后一句的em代表实体管理器EntityManager对象,点进去看一下:em会执行他的find方法

总结:
1.通过JdkDynamicAopProxy的invoke方法创建了一个动态代理对象
2.SimpleJpaRepository当中封装了JPA的操作(借助JPA的api完成数据库的CRUD)
3.通过hibernate完成数据库操作(封装了jdbc)

就到这里了 ,整过过程就是一个动态代理的实现过程,也就是动态代理帮助我们不用写那些基础的代码。表述的不清楚,主要是展示debugger的过程,相信跟着debugger一遍就会明白的。

9977

被折叠的 条评论
为什么被折叠?



