Mybatis mapper动态代理的原理详解(转)

在开始动态代理的原理讲解以前,我们先看一下集成mybatis以后dao层不使用动态代理以及使用动态代理的两种实现方式,通过对比我们自己实现dao层接口以及mybatis动态代理可以更加直观的展现出mybatis动态代理替我们所做的工作,有利于我们理解动态代理的过程,讲解完以后我们再进行动态代理的原理解析,此讲解基于mybatis的环境已经搭建完成,并且已经实现了基本的用户类编写以及用户类的Dao接口的声明,下面是Dao层的接口代码

一、Mybatis dao层两种实现方式的对比

dao层不使用动态代理的话,就需要我们自己实现dao层的接口,为了简便起见,我只是实现了Dao接口中的findAll方法,以此方法为例子来展现我们自己实现Dao的方式的情况,让我们来看代码:

这里的关键代码 List

注意:如果是添加,更新或者删除操作的话需要在方法中增加事务的提交。

使用动态代理的话Dao层的接口声明完成以后只需要在使用的时候通过SqlSession对象的getMapper方法获取对应Dao接口的代理对象,关键代码如下:

二、Mybatis动态代理实现方式的原理解析

动态代理中最重要的类:SqlSession、MapperProxy、MapperMethod,下面开始从入口方法到调用结束的过程分析。

  1. 调用方法的开始

因为SqlSesseion为接口,所以我们通过Debug方式发现这里使用的实现类为DefaultSqlSession。

  1. 找到DeaultSqlSession中的getMapper方法,发现这里没有做其他的动作,只是将工作继续抛到了Configuration类中,Configuration为类不是接口,可以直接进入该类的getMapper方法中

  2. 找到Configuration类的getMapper方法,这里也是将工作继续交到MapperRegistry的getMapper的方法中,所以我们继续向下进行。

  3. 找到MapperRegistry的getMapper的方法,看到这里发现和以前不一样了,通过MapperProxyFactory的命名方式我们知道这里将通过这个工厂生成我们所关注的MapperProxy的代理类,然后我们通过mapperProxyFactory.newInstance(sqlSession);进入MapperProxyFactory的newInstance方法中

  4. 找到MapperProxyFactory的newIntance方法,通过参数类型SqlSession可以得知,上面的调用先进入第二个newInstance方法中并创建我们所需要重点关注的MapperProxy对象,第二个方法中再调用第一个newInstance方法并将MapperProxy对象传入进去,根据该对象创建代理类并返回。这里已经得到需要的代理类了,但是我们的代理类所做的工作还得继续向下看MapperProxy类。

  5. 找到MapperProxy类,发现其确实实现了JDK动态代理必须实现的接口InvocationHandler,所以我们重点关注invoke()方法,这里看到在invoke方法里先获取MapperMethod类,然后调用mapperMethod.execute(),所以我们继续查看MapperMethod类的execute方法。

  6. 找到类MapperMethod类的execute方法,发现execute中通过调用本类中的其他方法获取并封装返回结果,我们来看一下MapperMethod整个类。

  7. MapperMethod类是整个代理机制的核心类,对SqlSession中的操作进行了封装使用。 该类里有两个内部类SqlCommand和MethodSignature。 SqlCommand用来封装CRUD操作,也就是我们在xml中配置的操作的节点。每个节点都会生成一个MappedStatement类。MethodSignature用来封装方法的参数以及返回类型,在execute的方法中我们发现在这里又回到了SqlSession中的接口调用,和我们自己实现UerDao接口的方式中直接用SqlSession对象调用DefaultSqlSession的实现类的方法是一样的,经过一大圈的代理又回到了原地,这就是整个动态代理的实现过程了。

Original: https://www.cnblogs.com/ajianbeyourself/p/15496741.html
Author: 奋斗终生
Title: Mybatis mapper动态代理的原理详解(转)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/543339/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Java学习-第一部分-第二阶段-项目实战:坦克大战【2】

    坦克大战【2】 笔记目录:(https://www.cnblogs.com/wenjie2000/p/16378441.html) 线程-应用到坦克大战 坦克大战0.3版 陆游曾说…

    Java 2023年6月15日
    089
  • 公众号资料分享

    在公众号分享两份资料一份是面试资料整理,面试资料针对Java方向,从JVM虚拟机到机器学习,云计算都有涉及,虽然机器学习有些内容比较简单,但是整体的知识框架还是列出来了,总结的非常…

    Java 2023年5月30日
    060
  • 给 zsh 自定义命令添加参数自动补全

    有时我会自定义一些 zsh 命令,以便提升某些高频操作的效率。本文记录我给一个自定义命令添加参数自动补全的方法。 场景 我自定义了一个 zsh 命令 gmt,执行 gmt <…

    Java 2023年6月5日
    092
  • 58.忘与记

    dsfds posted @2022-09-28 08:33 随遇而安== 阅读(3 ) 评论() 编辑 Original: https://www.cnblogs.com/55z…

    Java 2023年6月7日
    086
  • mysql

    一:什么情况下设置了索引但无法使用1.以%开头的like语句,模糊匹配2.or语句前后没有同时使用索引3.数据类型出现隐式转化 二:优化数据库的方法1.选取最适用的字段属性2.使用…

    Java 2023年6月5日
    096
  • SpringBoot技术优点

    一、SpringBoot的优势,使用它跟之前的对比,有什么改进。 1、什么是SpringBoot 答:Springboot是一个快速整合第三方框架,简化xml,内置Http服务器也…

    Java 2023年5月30日
    093
  • Java开发笔记(一百五十)C3P0连接池的用法

    JDBC既制定统一标准兼容了多种数据库,又利用预报告堵上了SQL注入漏洞,照理说已经很完善了,可是人算不如天算,它在性能方面不尽如人意。问题出在数据库连接的管理上,按照正常流程,每…

    Java 2023年6月6日
    058
  • 页面数据分页

    页面数据分页 导言 前端把每页的对象条数和当前页码发给后端,然后后端根据数值从数据库用SQL语句查询出来。 select * from t_table limit (pageNo …

    Java 2023年6月5日
    061
  • kubeadm 搭建 K8s

    kubeadm 搭建 K8s 本篇主要记录一下 使用 kubeadm 搭建 k8s 详细过程 ,环境使用 VirtualBox 构建的3台虚拟机 1.环境准备 操作系统:Cento…

    Java 2023年6月9日
    078
  • MySQL 索引简介

    索引的含义和特点 索引有其明显的优势,也有不可避免的缺点: 创建和维护索引同样需要耗费时间,并随着数据量的增加而增加 索引也会占用一定的物理空间 增加、删除和修改数据时,要动态地维…

    Java 2023年6月8日
    073
  • Java开发学习(十八)—-AOP通知获取数据(参数、返回值、异常)

    前面的博客我们写AOP仅仅是在原始方法前后追加一些操作,接下来我们要说说AOP中数据相关的内容,我们将从 &#x83B7;&#x53D6;&#x53C2;&…

    Java 2023年5月29日
    080
  • 约瑟夫问题

    这篇博客是我在B站看韩顺平老师的数据结构和算法的约瑟夫问题后的学习笔记,记录一下,防止忘记,也希望能帮到各位小伙伴。 问题引入:设编号为 1,2,… n 的 n 个人围…

    Java 2023年6月15日
    0106
  • Java常用的开发库推荐

    我是3y, 一年 CRUD 经验用十年的 markdown 程序员👨🏻‍💻 今天来讲讲来给大家聊聊开发提速的东西了: 工具包、 Lombok和 常用库 01、什么是工具包 基本上,…

    Java 2023年6月9日
    0102
  • docker打包Python项目成镜像文件

    做实验时因为数据太大用到了学校的服务器平台,在平台进行训练的时候首先需要搭建环境,由于种种原因,只能自己用docker来打包镜像文件,自己做镜像。记录一下遇到的坑以及解决方法。 d…

    Java 2023年6月5日
    084
  • 关于多工序、多资源排程场景下的新成果

    在之前关于资源与工序的场景中写了一篇不同资源与工序组合下,APS设计难度的文章. 并针对多工序、多工序场景下排程的初步设计。 关于生产计划排程的种类及其特性. 后来,针对多工序、多…

    Java 2023年6月16日
    090
  • 如此狂妄,自称高性能队列的Disruptor有啥来头?

    并发框架Disruptor 1. Disruptor概述 1.1 背景 ​ Disruptor是英国外汇交易公司LMAX开发的一个高性能队列,研发的初衷是解决内存队列的延迟问题(在…

    Java 2023年6月15日
    064
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球