讲师中心 微信公众号
AI工具推荐 视频效率加速

MyBatis的Mapper代理机制是怎样工作的_JDK动态代理生成接口实现类的原理

小浩小哥_3899

小浩小哥_3899

发布时间:2026-03-09 14:13:13

|

728人浏览过

|

来源于php中文网

原创

MyBatis 的 getMapper() 返回的是 JDK 动态代理对象而非真实实现类,它实现接口但所有方法调用均被 MapperProxy.invoke() 拦截;因 JDK 代理仅支持接口,故必须使用接口而非抽象类或普通类。

mybatis的mapper代理机制是怎样工作的_jdk动态代理生成接口实现类的原理

MyBatis 的 getMapper() 真的返回了一个“实现类”吗?

不,它返回的是一个 JDK 动态代理对象——没有生成 .class 文件,也没有编译期的实现类。这个代理对象实现了你声明的 UserMapper 接口,但所有方法调用都会被拦截到 MapperProxy.invoke() 中统一处理。

常见错误现象:有人在调试时试图在 IDE 里点进 userMapper.queryAll() 查看“实现源码”,结果跳转失败或进入空方法——因为根本不存在真实实现,只有代理逻辑。

  • getMapper(Class<t> type)</t> 最终委托给 MapperRegistry,从 knownMappers(HashMap)中查出对应的 MapperProxyFactory
  • 工厂调用 newInstance(sqlSession),内部执行 Proxy.newProxyInstance(..., new MapperProxy(...))
  • 代理对象本身不持有 SQL,SQL 解析、参数绑定、结果映射全部发生在 invoke() 被触发时

为什么必须用接口,不能用抽象类或普通类?

JDK 动态代理只支持对 接口 生成代理,这是 Java 语言层面的硬性限制。MyBatis 没有、也不能绕过这点。

使用场景:如果你误写了一个抽象类 AbstractUserMapper 并尝试 sqlSession.getMapper(AbstractUserMapper.class),会直接抛出 BindingException,提示 “Type is not known to the MapperRegistry”。

  • MyBatis 启动时只扫描并注册 @Mapper 接口或 <mapper class="..."></mapper> 中的接口类
  • 抽象类/普通类不会被放入 knownMappers,getMapper() 查不到就报错
  • 即使你手动把抽象类塞进 knownMappers,JDK 代理创建也会在 Proxy.newProxyInstance() 阶段失败

MapperProxy 和 MapperMethod 分工怎么理解?

MapperProxy 是“门卫”,只做拦截和分发;MapperMethod 是“业务员”,真正读 XML 或注解、解析 SQL、决定走 selectOne 还是 selectList。

容易踩的坑:以为缓存或日志逻辑该写在 MapperProxy 里——其实不该。它的 invoke() 方法极轻量,重逻辑(比如参数校验、慢 SQL 记录)应放在自定义插件或 Service 层。

  • MapperProxy 构造时就持有 SqlSession 和 methodCache(ConcurrentMap)
  • 首次调用某方法时,才根据 Method 对象构建 MapperMethod 并缓存;后续复用,避免重复解析 XML/注解
  • MapperMethod.execute() 内部根据 command.getType()(INSERT/SELECT 等)调用对应 SqlSession 方法,参数转换也在这里完成

不整合 Spring 时,getMapper() 的调用链你能跟到哪一层?

能清晰看到三层委托:你的代码 → DefaultSqlSession.getMapper() → Configuration.getMapper() → MapperRegistry.getMapper()。再往下就是 MapperProxyFactory.newInstance() 触发 JDK 代理创建。

性能影响:每次 getMapper() 都不新建代理对象,而是复用已创建的 MapperProxyFactory;但每个 SqlSession 实例都会拿到独立的代理对象(所以不同 session 的 mapper 不共享一级缓存)。

  • 代理对象生命周期 = SqlSession 生命周期;session 关闭后,其持有的 mapper 代理不可再用
  • 不要缓存 SqlSession 或它的 mapper 代理到静态变量或单例中,否则引发线程安全问题或连接泄漏
  • Spring 整合后,这些细节被隐藏,但底层仍是这套委托链——只是 SqlSession 由 SqlSessionTemplate 管理,代理对象由 MapperFactoryBean 创建

最常被忽略的一点:动态代理不是魔法,它依赖完整的元信息加载。如果 XML 文件没被正确 <mapper resource="..."></mapper> 引入,或注解 SQL 写错位置(比如放在 default 方法里),MapperMethod 构建就会失败,报错却可能出现在第一次调用时,而不是启动阶段。

热门AI工具

更多
墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

相关专题

更多
mybatis一级缓存和二级缓存
mybatis一级缓存和二级缓存

在MyBatis中,一级缓存和二级缓存是两种不同级别的缓存机制,它们都可以用来提高性能。本专题提供mybatis一级缓存和二级缓存相关文章,大家可以免费阅读。

583

2023.08.21

ibatis和mybatis有什么区别
ibatis和mybatis有什么区别

ibatis和mybatis的区别:1、基本信息不同;2、开发时间不同;3、功能与易用性;4、配置文件;5、入参类型与出参类型;6、返回结果集接受方式;7、语法差异;8、数据库方言支持;9、插件支持;10、社区活跃度;11、全球化支持。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2862

2024.02.23

mybatis如何配置数据库连接
mybatis如何配置数据库连接

mybatis配置数据库连接的方法:1、指定数据源;2、配置事务管理器;3、配置类型处理器和映射器;4、使用环境元素;5、配置别名。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

446

2024.02.23

mybatis工作原理及流程是什么
mybatis工作原理及流程是什么

mybatis工作原理及流程:1、配置文件;2、接口与映射;3、sql解析与生成;4、执行计划;5、结果处理;6、动态sql;7、缓存机制;8、插件;9、事务管理;10、日志与监控;11、扩展性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

292

2024.02.23

hibernate和mybatis有哪些区别
hibernate和mybatis有哪些区别

hibernate和mybatis的区别:1、实现方式;2、性能;3、对象管理的对比;4、缓存机制。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

302

2024.02.23

Java MyBatis框架
Java MyBatis框架

本专题专注于Java主流ORM框架MyBatis的应用,系统讲解SQL映射、动态SQL、结果映射、分页查询、缓存机制与多表关联等核心内容,并结合企业管理系统、电商平台和后台管理项目实战,帮助学员全面掌握高效的数据库持久层开发技能。

6249

2025.08.26

Uvicorn 报错与问题解决教程
Uvicorn 报错与问题解决教程

本专题汇总了Uvicorn服务器常见问题与报错解决的教程合集,涵盖启动失败、端口占用、模块导入错误、事件循环冲突及热重载失效等典型故障的排查思路。同时整理了多进程与Worker配置、SSL/HTTPS证书报错、跨域与代理配置等实战解决方案,助你快速定位并解决Uvicorn运行中的各类问题。

0

2026.11.02

Uvicorn使用教程
Uvicorn使用教程

本专题汇总了Uvicorn使用教程与启动运行指南,涵盖其作为Python ASGI服务器的定位与特点,以及命令行启动(uvicorn main:app --reload)、参数配置(host/port/workers)、程序内嵌运行与Gunicorn结合部署等核心用法。同时整理了热重载调试、日志配置与生产环境部署优化等技巧,助你快速掌握Uvicorn的运行与配置。

0

2026.11.02

Uvicorn安装配置教程
Uvicorn安装配置教程

本专题汇总了Uvicorn的安装配置教程与部署指南,涵盖通过pip安装Uvicorn、启动FastAPI/Starlette应用、开发模式热重载(--reload)及多进程工作模式配置等核心操作。同时整理了结合Gunicorn的生产部署方案、HTTPS与反向代理配置及性能调优技巧,助你快速完成Uvicorn服务的安装与上线部署。

0

2026.11.02

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn