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

news/2024/11/8 0:08:55/

我们在使用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.ppmy.cn/news/556403.html

相关文章

Redis 2023面试5题(七)

一、Redis redlock 实现原理 Redlock是一种基于Redis的分布式锁实现&#xff0c;它可以解决在分布式系统中由于主从切换、网络延迟等导致的锁竞争问题。 Redlock的实现原理如下&#xff1a; 创建多个Redis实例&#xff0c;每个实例都有相同的锁名称。使用Redis的SETNX命令尝试…

MongoDB基本使用(一)

MongoDB基本使用 Nosql简介 NoSQL(NoSQL Not Only SQL )&#xff0c;意即”不仅仅是SQL”。 在现代的计算系统上每天网络上都会产生庞大的数据量&#xff0c; 这些数据有很大一部分是由关系数据库管理系统&#xff08;RDBMS&#xff09;来处理。 1970年 E.F.Codd’s提出的关系…

操作系统概述(二、入门,基础,计算机系统)

系列文章目录 文章目录 系列文章目录前言九、操作系统状态机模型&#xff08;系统加载&#xff09;软件和硬件的桥梁操作系统状态机模型 十、状态机模型的应用查看状态机执行 总结 前言 九、操作系统状态机模型&#xff08;系统加载&#xff09; 软件和硬件的桥梁操作系统的加…

已解决:PhotoShop导出发生未知错误!!!

在编辑->首选项->技术预览 勾选“启用优化的导出为”即可。

关于注册苹果开发者账号时登录遇到的提示未知错误

使用新的 Apple Developer app 注册时如果手机只登陆了Apple ID(即只登陆了应用商店而没有登录iCloud) 那么会提示未知错误请再试一次的提示&#xff0c;所以解决方法就是需要同时登录应用商店&#xff08;App Store账号&#xff09;Apple Id并打开iCloud。 再次尝试登录就OK了…

Mac/Macbook Apple ID 无法登录:验证失败,发生未知错误

亲测可用的解决方案&#xff1a; 关机开机&#xff0c;按住Shift键直到出现登录框登录&#xff0c;然后会再出现一次登录框&#xff0c;此时右上角会有“安全启动”的字再登录&#xff0c;进入系统后进系统偏好设置&#xff0c;登录看看&#xff0c;应该可以成功~

向windows服务器传输大文件时提示未知错误解决方法

1.打开远程登录的对话窗口&#xff0c;选择选项按钮&#xff0c;点击本地资源&#xff0c;在本地资源和设备这一项上点击详细信息 2.展开驱动器&#xff0c;勾选需要传输文件所在的磁盘&#xff0c;也可全部勾选 3.再远程登录至服务器&#xff0c;在“我的电脑”里面选择本地…

Microsoft Visual Studio 2010 运行报未知错误

问题&#xff1a; 安装Microsoft Visual Studio 2010后&#xff0c;重新打开Microsoft Visual Studio 2010&#xff0c;发现无法打开&#xff0c;报未知错误&#xff01;&#xff01; 解决办法&#xff1a; 1、关闭杀毒软件 2、右键以管理员身份运行