Mybatis源码分析_Mapper接口是如何实例化的 (2)

news2024/11/20 1:36:56

我们在使用Spring+mybatis的时候,经常都是直接写一个接口和一个对应的 ***Mapper.xml文件,然后业务代码就可以直接注入这个接口了。它是如何做到的呢?

接口:

xml

 

 想搞清楚这个问题,那还是要从Mybatis底层源码进行分析的。Mybatis是一个非常优先的框架,它大量的将所谓的设计模式运用到了底层源码当中。对于不太了解动态代理设计模式的,可以参考我的另外2篇博客

《大话设计模式》——读后感 (4)为别人做嫁衣?——动态代理模式(2)_chen_yao_kerr的博客-CSDN博客

Spring之AOP技术 (6)_chen_yao_kerr的博客-CSDN博客 

了解了动态代理技术,在Mybatis中,我们需要关注一个类 MapperProxyFactory。说的简单点,这个类就是负责根据接口与sqlSession来创建MapperProxy对象的  。

/*
 *    Copyright ${license.git.copyrightYears} the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.apache.ibatis.binding;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.ibatis.session.SqlSession;

/**
 *
 * 用于生成mapper接口动态代理的实例对象;
 * @author Lasse Voss
 */
public class MapperProxyFactory<T> {

  //mapper接口的class对象
  private final Class<T> mapperInterface;
  //key是mapper接口中的某个方法的method对象,value是对应的MapperMethod,MapperMethod对象不记录任何状态信息,所以它可以在多个代理对象之间共享
  private final Map<Method, MapperMethod> methodCache = new ConcurrentHashMap<>();

  public MapperProxyFactory(Class<T> mapperInterface) {
    this.mapperInterface = mapperInterface;
  }

  public Class<T> getMapperInterface() {
    return mapperInterface;
  }

  public Map<Method, MapperMethod> getMethodCache() {
    return methodCache;
  }

  @SuppressWarnings("unchecked")
  protected T newInstance(MapperProxy<T> mapperProxy) {
	//创建实现了mapper接口的动态代理对象
    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
  }

  public T newInstance(SqlSession sqlSession) {
	 //每次调用都会创建新的MapperProxy对象
    final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);
    return newInstance(mapperProxy);
  }

}

  

而MapperProxy干嘛的呢?其实,它就是实现了 InvocationHandler 接口的一个动态代理类.  我们之前学习动态代理的时候,不仅要给动态代理类传递接口信息,还要传递这个业务接口的具体实现类。这样,动态代理就可以代理具体的业务实现类了。

 

但是,在MapperProxy中,我们并没有这样的实现类,反而是直接持有了接口信息,思考一下为什么呢?

ok,言归正传。我们知道了MapperProxyFactory就是负责创建MapperProxy对象的,而这个对象是一个动态代理类,也就是说它可以根据  业务接口与sqlSession信息 生成一个代理类。

此处是不是非常的精妙,动态代理设计模式 与 简单工厂设计模式 的典型运用。

那么,整个流程是什么样的呢?

1.  就是sqlSession对象调用getMapper方法,最终进入了 MapperRegistry类的getMapper方法。

 

2.  在这个方法中,我们直接获取到MapperProxyFactory对象,并且直接调用 newInstance方法

3. 而MapperProxyFactory的newInstance方法,就是负责创建动态代理类的。

因此,mybatis的接口是无法被实例化的。实例化的是一个持有该接口信息的动态代理类。 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/680850.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

智能小车使用IIC屏幕做动作显示界面

一、简介 使用0.96寸IIC屏幕作为遥控动作的显示界面。 外设引脚 stm32f103c8t6单片机IIC引脚有两组 使用I2C1&#xff0c;对应的时钟与数据线分别为PB6、PB7。 IIC屏幕指令 // OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel // OLED_WR_Byte(0x00,OLED_CMD);//---se…

07- c语言指针 (C语言)

一 指针的引入 1、一般把内存中的一个字节称为一个内存单元。 2、为了正确地访问这些内存单元&#xff0c;必须为每个内存单元编上号。根据一个内存单元的编号即可准确地找到该内存单元。内存单元的编号也叫做地址&#xff0c;通常也把这个地址称为指针。 3、如果在程序中定义…

车载网络测试 - CANCANFD - 基础篇_03

十、发送方式与过滤方式 1、广播发送及规则 我们以小组讨论现场为例来说明CAN总线广播发送规则&#xff1a; 1&#xff09;一个房间代表同一路CAN总线&#xff0c;每一个小组代表一个CAN Node&#xff0c;每一个小组成员发言代表发送一帧CAN报文&#xff0c;对所有的小组成员进…

生成对抗网络

1 GAN基本概念 1.1 GAN介绍 GAN的英文全称是Generative Adversarial Network&#xff0c;中文名是生成对抗网络。它由两个部分组成&#xff0c;生成器和鉴别器&#xff08;又称判别器&#xff09;&#xff0c;生成网络&#xff08;Generator&#xff09;负责生成模拟数据&…

【Python】异常处理 ④ ( 异常处理 else 语句 | 异常处理 finally 语句 )

文章目录 一、Python 异常捕获 else 语句1、异常捕获 else 语句2、代码示例 - 没有触发 else 语句的情况3、代码示例 - 触发 else 语句的情况 二、Python 异常捕获 finally 语句1、异常捕获 finally 语句2、代码示例 - 出现异常后执行 finally 语句 一、Python 异常捕获 else 语…

展示和标注图像:探索Gradio AnnotatedImage模块的功能

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

代码生成器原理分析

代码生成器原理分析 理解代码生成器的需求和实现思路掌握freemaker的使用 理解数据库中的元数据完成环境搭建工作 浅谈代码生成器 概述 在项目开发过程中&#xff0c;关注点更多是在业务功能的开发及保证业务流程的正确性上&#xff0c;对于重复性的代码编写占据了程 序员…

指标综合评价(定性指标定量化、指标正相关化、赋权重)

目录 一、定性指标定量化 二、将指标同型化 线性比例变换法 极差变换法 二、评价指标赋予权重 三、综合评价 战斗机性能的综合评价问题 例&#xff1a;战斗机的性能指标主要包括最大速度、飞行半径、最大负载、隐身性能、垂直起降性能、可靠性、灵敏度等指标和相关费用。…

Vue+Element UI 生鲜管理系统简介及项目搭建,页面布局(一)

文章目录 浅谈一、背景二、搭建创建vue项目vue项目结构简介安装Element UI库安装axios安装querystring安装normalize.css安装echarts运行删除无用组件基础css样式导入 三、页面布局配置路由布局flex布局&#xff08;弹性盒子&#xff09;固定布局固定布局配置路由 浅谈 自从入…

【Rust】2、实战:文件、网络、时间、进程-线程-容器、内核、信号-中断-异常

文章目录 七、文件和存储7.2 serde 与 bincode 序列化7.3 实现一个 hexdump7.4 操作文件7.4.1 打开文件7.4.2 用 std::fs::Path 交互 7.5 基于 append 模式实现 kv数据库7.5.1 kv 模型7.5.2 命令行接口 7.6 前端代码7.6.1 用条件编译定制要编译的内容 7.7 核心&#xff1a;LIBA…

【Java高级语法】(十五)lambda表达式:给你一颗语法糖Lambda,解析函数式编程的杰作~

Java高级语法详解之lambda表达式 1️⃣ 概念2️⃣ 优势和缺点3️⃣ 使用3.1 语法结构3.2 案例3.2.1 无参Lambda3.2.2 带有一个参数3.2.3 带有多个参数3.2.4 方法引用的简化形式 4️⃣ 应用场景5️⃣ 优化技巧6️⃣ 原理7️⃣ 注意性能问题&#x1f33e; 总结 1️⃣ 概念 Java …

架构设计第十一讲:架构之高并发:限流

架构设计第十一讲&#xff1a;架构之高并发&#xff1a;限流 每个系统都有服务的上线&#xff0c;所以当流量超过服务极限能力时&#xff0c;系统可能会出现卡死、崩溃的情况&#xff0c;所以就有了降级和限流。限流其实就是&#xff1a;当高并发或者瞬时高并发时&#xff0c;为…

rabbitmq第三课-RabbitMQ高级功能详解以及常用插件实战

一、选择合适的队列. 实际上是可以选择三种队列类型的&#xff0c;classic经典队列&#xff0c;Quorum仲裁队列&#xff0c;Stream流式队列。 后面这两种队列也是RabbitMQ在最近的几个大的版本中推出的新的队列类型。3.8.x推出了Quorum仲裁队列&#xff0c;3.9.x推出了Stream流…

MyBatis何时使用一级缓存,何时使用二级缓存?

Mybatis设计2级缓存来提升数据检索效率&#xff0c;避免每次都查询数据库。 一、一级缓存 一级缓存 Mybatis 的一级缓存是指 SQLSession&#xff0c;一级缓存的作用域是 SQlSession , Mabits 默认开启一级缓存。 在同一个SqlSession中&#xff0c;执行相同的SQL查询时&#x…

基于STM32CUBEMX驱动TOF模块VL6180与VL6180X(2)----修改测量范围

概述 当使用VL6180传感器进行测距时&#xff0c;可以通过修改缩放因子来改变可测量的距离范围。VL6180是一种基于飞行时间原理的传感器&#xff0c;通过测量光信号的往返时间来确定物体与传感器之间的距离。 默认情况下&#xff0c;VL6180传感器的测距范围约为0至200毫米。然…

显卡检测工具:GPU-Z

今天小编为大家测试了一款轻量级的GPU显卡的测试工具&#xff0c;可以查看GPU的详细信息&#xff0c;以供各位同学们学习。 一、简单介绍 GPU-Z是一款方便实用的软件工具&#xff0c;专门为用户提供视频卡和GPU的详尽信息。它具有轻巧的特点&#xff0c;不需要安装即可使用&am…

2023版智慧高速智慧公路总体建设方案,售前人员必备方案

导读&#xff1a;原文《智慧高速智慧公路总体建设方案》共83页PPT&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 如需获取完整的电子版内容参考学习 您可以关注评论…

【雷达原理】基本雷达方程的推导

基本雷达方程 一、研究目的二、推导过程1、基本雷达方程常用的表达形式2、计算案例3、仿真代码 参考文献 一、研究目的 雷达方程定量地描述了作用距离与雷达参数及目标特性之间的关系。 研究雷达方程主要有以下作用&#xff1a; &#xff08;1&#xff09;根据雷达参数来估算雷…

慕课:笔记

课程链接&#xff1a;直面JavaScript中的30个疑难杂症_JavaScript面试题-慕课网 第二章&#xff1a;数据类型 数据类型是每门编程语言的必修之课&#xff0c;你是否对JavaScript的数据类型和检测存在困惑&#xff0c;本章节将为你揭晓其中的奥秘&#xff0c;让你对数据类型有…

矩阵压缩算法

当矩阵中存在着重复元素时&#xff0c;为了节省空间会采用压缩算法&#xff0c;关键在于原矩阵空间与压缩后数据结构的对应&#xff1b; 1.对称压缩&#xff1a;数据沿对角线对称的情况&#xff1b; 将矩阵压缩为一维数组&#xff0c;数组的长度是&#xff1a; 对于num[n][n…