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

我们在使用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的接口是无法被实例化的。实例化的是一个持有该接口信息的动态代理类。 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

轻量级的深度学习框架Tinygrad

Tinygrad是一个轻量级的深度学习库&#xff0c;它提供了一种简化和直观的方法来理解和实现神经网络。在本文中&#xff0c;我们将探讨Tinygrad及其主要功能&#xff0c;以及它如何成为那些开始深度学习之旅的人的有价值的工具。 什么是Tinygrad? Tinygrad是一个开源的深度学习…

Redis 通用命令

通用命令介绍 Redis 通用命令是一些 Redis 下可以作用在常用数据结构上的常用命令和一些基础的命令&#xff0c;比如删除键、对键进行改名、判断键是否存在等。简单说&#xff0c;就是 keys 分类的命令&#xff0c;如下图。 上图中圈中的部分&#xff0c;就是所谓的通用的命令…

【C语言初阶】带你轻松玩转所有常用操作符(1)

君兮_的个人主页 勤时当勉励 岁月不待人 C/C 游戏开发 Hello,这里是君兮_&#xff0c;最近要准备期末复习了&#xff0c;可能更新的就不会那么频繁了&#xff0c;下个星期回复正常更新。 操作符详解1 前言一.操作符的分类二.算数操作符三.移位操作符1.二进制表示的三种形式2.…

matlab实现语音信号的频域分析及应用

1.语音信号本质上是非平稳信号。但我们可以假设语音信号在一个短时间内是平稳的&#xff0c;这样我们用稳态分析方法处理非平稳信号。应用在傅立叶分析就是短时傅立叶变换。 语音的频域分析&#xff1a;包括语音信号的频谱、功率谱、倒频谱、频谱包络等. 常用频域分析方法&am…

mySql和VSC++

确认主机服务里的mysql服务已打开 使用组合键“winR”运行“services.msc”&#xff0c;进入本地服务窗口&#xff1b; 2.进入本地服务窗口后&#xff0c;在右侧服务列表中&#xff0c;查找到“ mysql ”服务选项&#xff1b; 3.查找到mysql服务选项后&#xff0c;双击打开mysq…

linux安装anaconda

linux安装anaconda 1、下载anaconda&#xff1a; Conda 是一个强大的包管理器和环境管理器&#xff0c;您可以在 Windows 的 Anaconda Prompt 或 macOS 或 Linux 的终端窗口中与命令行命令一起使用。 换句话说&#xff0c;我把Conda理解为前端的npm或yarn&#xff0c;后端的…

二进制部署k8集群(上)搭建单机matser和etcd集群

1. 单机matser预部署设计 组件部署&#xff1a; 2.操作系统初始化配置 注意&#xff1a;该操作在所有node节点上进行&#xff0c;为k8s集群提供适合的初始化部署环境 #关闭防火墙 systemctl stop firewalld systemctl disable firewalld iptables -F && iptables -t n…

Java-三种基本控制结构及相关面试题

文章目录 前言一、 顺序控制结构1.1 概念1.2 代码1.3 NS图中体现 二、分支控制结构2.1 概念2.2 if语句2.3 switch语句2.4 NS图中的体现 三、循环控制结构3.1 概念3.2 for循环3.3 while循环3.4 do-while循环3.5 增强 for 循环NS图中的体现 四、相关面试题什么是控制流语句&#…

从零开始:如何用Python建立你的第一个人工智能模型

1. 摘要&#xff1a; 在这篇文章中&#xff0c;我们将介绍如何从零开始使用Python建立你的第一个人工智能模型。无论你是刚接触编程的新手&#xff0c;还是有经验的开发者想进一步探索人工智能领域&#xff0c;这篇文章都将为你提供清晰、详细的指南。我们将一步步探索数据预处…

macOS Monterey 12.6.7 (21G651) Boot ISO 原版可引导镜像

macOS Monterey 12.6.7 (21G651) Boot ISO 原版可引导镜像 本站下载的 macOS 软件包&#xff0c;既可以拖拽到 Applications&#xff08;应用程序&#xff09;下直接安装&#xff0c;也可以制作启动 U 盘安装&#xff0c;或者在虚拟机中启动安装。另外也支持在 Windows 和 Lin…

2023年大学计算机专业实习心得14篇

2023年大学计算机专业实习心得精选篇1 20__年已然向我们挥手告别而去了。在20__年初之际&#xff0c;让我们对过去一年的工作做个总结。忙碌的一年里&#xff0c;在领导及各位同事的帮助下&#xff0c;我顺利的完成了20__年的工作。为了今后更好的工作&#xff0c;总结经验&…

《Java黑皮书基础篇第10版》 第17章【笔记】

第十七章 二进制I/O 17.1 引言 文件可以不严谨的分类为文本文件和二进制文件。文本文件指的是可以用文件编辑器进行查看和修改的&#xff0c;二进制文件则不可以使用文本编辑器查看和修改。 例如&#xff0c;Test.java文件储存在文本文件中&#xff0c;因此可以用文本编辑器…

Web安全测试中常见逻辑漏洞解析(实战篇)

前言&#xff1a; 越权漏洞是比较常见的漏洞类型&#xff0c;越权漏洞可以理解为&#xff0c;一个正常的用户A通常只能够对自己的一些信息进行增删改查&#xff0c;但是由于程序员的一时疏忽&#xff0c;对信息进行增删改查的时候没有进行一个判断&#xff0c;判断所需要操作的…

leetcode188. 买卖股票的最佳时机 IV.动态规划-java

买卖股票的最佳时机 IV leetcode188. 买卖股票的最佳时机 IV题目描述 动态规划代码演示 动态规划专题 leetcode188. 买卖股票的最佳时机 IV 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problems/best-time-to-buy-and-sell-st…

从零构建后端项目-创建SpringBoot项目配置MyBatis

目录 主体介绍 创建SpringBoot项目主要步骤 配置MyBatis 整合高级功能 创建SpringBoot项目 配置Tomcat 配置MySQL数据源 配置Redis数据源 配置MongoDB数据源 运行项目&#xff0c;检测配置 配置MyBatis 创建IDEA数据库连接 生成MyBatis各种文件 配置MyBatis 配…

自然语言处理从入门到应用——静态词向量预训练模型:神经网络语言模型(Neural Network Language Model)

分类目录&#xff1a;《自然语言处理从入门到应用》总目录 《自然语言处理从入门到应用——自然语言处理的语言模型&#xff08;Language Model&#xff0c;LM&#xff09;》中介绍了语言模型的基本概念&#xff0c;以及经典的基于离散符号表示的N元语言模型&#xff08;N-gram…

【Redis基础】

Redis基础 Redis基础Note Redis基础1.初识Redis1.1.认识NoSQL1.1.1.结构化与非结构化1.1.2.关联和非关联1.1.3.查询方式1.1.4.事务1.1.5.总结 1.2.认识Redis1.3.安装Redis1.3.1.依赖库1.3.2.上传安装包并解压1.3.3.启动1.3.4.默认启动1.3.5.指定配置启动1.3.6.开机自启1.3.7.wi…

Win7系统提示Windows Defender无法扫描选定的文件解决方法

Win7 64位系统提示“Windows Defender无法扫描选定的文件”怎么办呢?使用Windows Defender扫描文件,结果弹出如下图窗口,该怎么解决呢,参考下文,一起来解决Win7系统提示“Windows Defender无法扫描选定的文件”的解决方法。 原因分析: 这是因为开启Defender扫描压…

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

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

计算机网络基础知识(九)—— 什么是TelnetS?Telnet Over TLS

文章目录 01 | TelnetS02 | OpenSSL03 | 实现思路服务器处理流程客户端处理流程 04 | 代码实现服务端代码客户端代码编译过程 & 执行结果 前面学习了什么是HTTPS协议&#xff0c;了解了HTTPS的工作原理以及具体的工作流程&#xff0c;了解了HTTP协议和HTTPS协议之间的区别。…