您当前的位置:首页 > 电脑百科 > 程序开发 > 框架

聊聊Mybatis的binding模块

时间:2022-08-12 13:53:18  来源:  作者:Java那点事儿

聊聊MyBatis的binding模块

为什么我们在使用Mybatis的时候只需要写接口和xml文件就能执行sql呢?这就是Mybatis的binding模块需要做的事情了,今天我们分析一下Mybatis的binding模块,binding包下的类主要有四个MApperRegistry、MapperProxyFactory、MapperProxy和MapperMethod

映射注册类MapperRegistry

MapperRegistry是个注册类,它的knownMappers集合保存着Mapper接口和MapperProxyFactory实例的映射关系

它的addMapper()方法就是添加映射关系的方法:

public <T> void addMapper(Class<T> type) {    if (type.isInterface()) {      if (hasMapper(type)) {        throw new BindingException("Type " + type + " is already known to the MapperRegistry.");      }      boolean loadCompleted = false;      try {        knownMappers.put(type, new MapperProxyFactory<>(type));        // It's important that the type is added before the parser is run        // otherwise the binding may automatically be attempted by the        // mapper parser. If the type is already known, it won't try.        MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);        parser.parse();        loadCompleted = true;      } finally {        if (!loadCompleted) {          knownMappers.remove(type);        }      }    }  }

当传入的type是个接口并knownMappers中没有,就把type和对应的MapperProxyFactory实例放入knownMappers中

然后在执行sql的时候,Mybatis会调用MapperRegistry.getMapper()方法

@SuppressWarnings("unchecked")  public <T> T getMapper(Class<T> type, SqlSession sqlSession) {    final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);    if (mapperProxyFactory == null) {      throw new BindingException("Type " + type + " is not known to the MapperRegistry.");    }    try {      return mapperProxyFactory.newInstance(sqlSession);    } catch (Exception e) {      throw new BindingException("Error getting mapper instance. Cause: " + e, e);    }  }
  1. 先从knownMappers集合中找到对应的MapperProxyFactory实例
  2. 然后调用newInstance()方法
  3. 映射代理工厂类MapperProxyFactory
  4. MapperProxyFactory的newInstance()方法:
public T newInstance(SqlSession sqlSession) {    final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);    return newInstance(mapperProxy);  }  @SuppressWarnings("unchecked")  protected T newInstance(MapperProxy<T> mapperProxy) {    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);  }

生成mapperInterface接口 的代理对象的实例,代理类是MapperProxy,它实现了InvocationHandler,利用jdk动态代理生成代理对象

看一下它重写的invoke()方法:

映射代理类MapperProxy

MapperProxy的invoke()方法:

@Override  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {    try {      if (Object.class.equals(method.getDeclaringClass())) {        return method.invoke(this, args);      } else {        return cachedInvoker(method).invoke(proxy, method, args, sqlSession);      }    } catch (Throwable t) {      throw ExceptionUtil.unwrapThrowable(t);    }  }

不是Object的类会被拦截,拦截调用cachedInvoker()方法,其他执行invoke()方法,

private MapperMethodInvoker cachedInvoker(Method method) throws Throwable {    try {      return MapUtil.computeIfAbsent(methodCache, method, m -> {        if (m.isDefault()) {          try {            if (privateLookupInMethod == null) {              return new DefaultMethodInvoker(getMethodHandleJAVA8(method));            } else {              return new DefaultMethodInvoker(getMethodHandleJava9(method));            }          } catch (IllegalAccessException | InstantiationException | InvocationTargetException              | NoSuchMethodException e) {            throw new RuntimeException(e);          }        } else {          return new PlAInMethodInvoker(new MapperMethod(mapperInterface, method, sqlSession.getConfiguration()));        }      });    } catch (RuntimeException re) {      Throwable cause = re.getCause();      throw cause == null ? re : cause;    }  }
  1. 从methodCache中获取对应的MapperMethodInvoker
  2. 如果缓存没有,如果是方法是default方法就创建DefaultMethodInvoker对象,否则创建PlainMethodInvoker对象
  3. 默认方法调用类DefaultMethodInvoker
  4. 对于DefaultMethodInvoker类通过MethodHandle完成调用
private static class DefaultMethodInvoker implements MapperMethodInvoker {    private final MethodHandle methodHandle;    public DefaultMethodInvoker(MethodHandle methodHandle) {      super();      this.methodHandle = methodHandle;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args, SqlSession sqlSession) throws Throwable {      return methodHandle.bindTo(proxy).invokeWithArguments(args);    }  }

对于普通方法对应的类PlainMethodInvoker通过MapperMethod来完成调用,

private static class PlainMethodInvoker implements MapperMethodInvoker {    private final MapperMethod mapperMethod;    public PlainMethodInvoker(MapperMethod mapperMethod) {      super();      this.mapperMethod = mapperMethod;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args, SqlSession sqlSession) throws Throwable {      return mapperMethod.execute(sqlSession, args);    }  }

总结

这篇文章主要介绍了聊聊Mybatis的binding模块,它的MapperRegistry保存着Mapper接口和MapperProxyFactory实例的映射关系,而MapperProxyFactory是一个的工厂,生成的是Mapper接口的代理类,MapperProxy实现InvocationHandler,重写invoke()方法进行拦截处理,根据方法判断是不是default类型创建不同的MethodInvoker类,然后调用MapperMethod执行sql,下篇文章我们将介绍MapperMethod类



Tags:   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
短剧备案新规出台 风口“捞金”不确定性增加
某省旅游和文化广电体育厅《关于微短剧备案最新工作提示》的文件在网络上传播。文件称,各平台要将目前未经备案上线播出的微短剧剧目相关信息,于2024年5月31日前报所属地省级...【详细内容】
2024-04-12  Search:   点击:(1)  评论:(0)  加入收藏
陪诊师不再“三无”:上海首期培训百人,两项团体标准正起草
来源:“新民晚报”微信公众号上海陪诊师培训要开班了。消息不胫而走,这几天上海开放大学的总机电话几乎被打爆了。在上海,陪诊师还处于“灰色地带”,没有从业门槛、没有岗前培训...【详细内容】
2024-04-12  Search:   点击:(2)  评论:(0)  加入收藏
今天为何依旧需要规培?如何让规培生走好这条必经之路?
2020年,全国首档医生观察纪实节目《我的白大褂》首次聚焦了一个年轻群体&mdash;&mdash;90后规培生。一则来自医学生的观后留言说道,“规培的意义,就是过渡成为一个好的临床医生...【详细内容】
2024-04-12  Search:   点击:(2)  评论:(0)  加入收藏
大学选修课如何才能受追捧
 因为没排上课,北京师范大学副教授陈志新将自己的课堂搬到网络上,免费教起了“社会科学概论”课。此举不但受到网友追捧,也引发了人们对大学选修课的关注。那么,高校的选修课通...【详细内容】
2024-04-12  Search:   点击:(1)  评论:(0)  加入收藏
单瓶跌至2500!飞天茅台价格走低,究竟是何原因?
本报记者 孙吉正 北京报道近日,飞天茅台市场售价走低成为大众关注的焦点。日前,有大量经销商反映飞天茅台开始出现市场价格跳水的情况。根据《中国经营报》记者了解,截至发稿,单...【详细内容】
2024-04-12  Search:   点击:(2)  评论:(0)  加入收藏
数字求职机亮相杭州高铁站 “刷脸”也能找工作
中新网杭州4月11日电(鲍梦妮 黄俊杰)近日,杭州西站、杭州东站等地纷纷出现数字求职机的身影。其通过人脸识别技术,可帮助各地来杭青年实现轻松面试,“刷脸”找工作。求职者在杭...【详细内容】
2024-04-12  Search:   点击:(2)  评论:(0)  加入收藏
AI未来或超越“最聪明的人”?专家谈发展如何兼顾公平
中新社北京4月11日电 (记者 马帅莎)到明年底或2026年,人工智能(AI)或超越“最聪明的人”,美国知名企业家埃隆&middot;马斯克近日对人工智能的这一大胆猜想引起关注,这比他去年...【详细内容】
2024-04-12  Search:   点击:(2)  评论:(0)  加入收藏
不合理差评的“紧箍”如何松一松?
投诉背后有委屈,服务分被扣难升级,差错责任分配待完善不合理差评的“紧箍”如何松一松?本报记者 周子元 于灵歌《工人日报》(2024年04月12日 05版)阅读提示扣分、罚款、降低排...【详细内容】
2024-04-12  Search:   点击:(2)  评论:(0)  加入收藏
网络渠道“眼见”不一定为实 防范“AI换脸”诈骗行为
防范“AI换脸”诈骗行为本报记者 屈信明《 人民日报 》( 2024年04月12日 第 19 版)近年来,多个行业创新人工智能技术应用场景,银行智能机器人、虚拟主持人等为社会公众提供了...【详细内容】
2024-04-12  Search:   点击:(2)  评论:(0)  加入收藏
银行卡90分钟被盗刷283次谁之过?法院这样判决
银行卡90分钟被盗刷283次谁之过法院判决银行对用户损失担责本报记者  张雪泓本报通讯员 刘 雨短短一个半小时内,李女士的储蓄卡发生了283笔交易,金额均为1000元。李女士认为,...【详细内容】
2024-04-12  Search:   点击:(2)  评论:(0)  加入收藏
▌简易百科推荐
Web Components实践:如何搭建一个框架无关的AI组件库
一、让人又爱又恨的Web ComponentsWeb Components是一种用于构建可重用的Web元素的技术。它允许开发者创建自定义的HTML元素,这些元素可以在不同的Web应用程序中重复使用,并且...【详细内容】
2024-04-03  京东云开发者    Tags:Web Components   点击:(8)  评论:(0)  加入收藏
Kubernetes 集群 CPU 使用率只有 13% :这下大家该知道如何省钱了
作者 | THE STACK译者 | 刘雅梦策划 | Tina根据 CAST AI 对 4000 个 Kubernetes 集群的分析,Kubernetes 集群通常只使用 13% 的 CPU 和平均 20% 的内存,这表明存在严重的过度...【详细内容】
2024-03-08  InfoQ    Tags:Kubernetes   点击:(15)  评论:(0)  加入收藏
Spring Security:保障应用安全的利器
SpringSecurity作为一个功能强大的安全框架,为Java应用程序提供了全面的安全保障,包括认证、授权、防护和集成等方面。本文将介绍SpringSecurity在这些方面的特性和优势,以及它...【详细内容】
2024-02-27  风舞凋零叶    Tags:Spring Security   点击:(54)  评论:(0)  加入收藏
五大跨平台桌面应用开发框架:Electron、Tauri、Flutter等
一、什么是跨平台桌面应用开发框架跨平台桌面应用开发框架是一种工具或框架,它允许开发者使用一种统一的代码库或语言来创建能够在多个操作系统上运行的桌面应用程序。传统上...【详细内容】
2024-02-26  贝格前端工场    Tags:框架   点击:(47)  评论:(0)  加入收藏
Spring Security权限控制框架使用指南
在常用的后台管理系统中,通常都会有访问权限控制的需求,用于限制不同人员对于接口的访问能力,如果用户不具备指定的权限,则不能访问某些接口。本文将用 waynboot-mall 项目举例...【详细内容】
2024-02-19  程序员wayn  微信公众号  Tags:Spring   点击:(39)  评论:(0)  加入收藏
开发者的Kubernetes懒人指南
你可以将本文作为开发者快速了解 Kubernetes 的指南。从基础知识到更高级的主题,如 Helm Chart,以及所有这些如何影响你作为开发者。译自Kubernetes for Lazy Developers。作...【详细内容】
2024-02-01  云云众生s  微信公众号  Tags:Kubernetes   点击:(51)  评论:(0)  加入收藏
链世界:一种简单而有效的人类行为Agent模型强化学习框架
强化学习是一种机器学习的方法,它通过让智能体(Agent)与环境交互,从而学习如何选择最优的行动来最大化累积的奖励。强化学习在许多领域都有广泛的应用,例如游戏、机器人、自动驾...【详细内容】
2024-01-30  大噬元兽  微信公众号  Tags:框架   点击:(68)  评论:(0)  加入收藏
Spring实现Kafka重试Topic,真的太香了
概述Kafka的强大功能之一是每个分区都有一个Consumer的偏移值。该偏移值是消费者将读取的下一条消息的值。可以自动或手动增加该值。如果我们由于错误而无法处理消息并想重...【详细内容】
2024-01-26  HELLO程序员  微信公众号  Tags:Spring   点击:(88)  评论:(0)  加入收藏
SpringBoot如何实现缓存预热?
缓存预热是指在 Spring Boot 项目启动时,预先将数据加载到缓存系统(如 Redis)中的一种机制。那么问题来了,在 Spring Boot 项目启动之后,在什么时候?在哪里可以将数据加载到缓存系...【详细内容】
2024-01-19   Java中文社群  微信公众号  Tags:SpringBoot   点击:(86)  评论:(0)  加入收藏
花 15 分钟把 Express.js 搞明白,全栈没有那么难
Express 是老牌的 Node.js 框架,以简单和轻量著称,几行代码就可以启动一个 HTTP 服务器。市面上主流的 Node.js 框架,如 Egg.js、Nest.js 等都与 Express 息息相关。Express 框...【详细内容】
2024-01-16  程序员成功  微信公众号  Tags:Express.js   点击:(88)  评论:(0)  加入收藏
相关文章
    无相关信息
站内最新
站内热门
站内头条