设计模式之美
王争
前 Google 工程师,《数据结构与算法之美》专栏作者
123426 人已学习
新⼈⾸单¥98
登录后,你可以任选6讲全文学习
课程目录
已完结/共 113 讲
设计模式与范式:行为型 (18讲)
设计模式之美
15
15
1.0x
00:00/00:00
登录|注册

88 | 开源实战五(中):如何利用职责链与代理模式实现MyBatis Plugin?

pluginAll()方法
Executor、StatementHandler、ParameterHandler、ResultSetHandler的创建
Interceptor注入到InterceptorChain
解析配置文件
invoke()方法
wrap()方法
动态代理
plugin()方法
intercept()方法
MyBatis Plugin的限制
实现思路的差异
职责链模式的应用场景
源码解析
Plugin类
Interceptor和InterceptorChain
例子:统计SQL执行耗时
拦截MyBatis执行SQL的过程
类似于Servlet Filter和Spring Interceptor
ORM框架对比
课堂讨论
重点回顾
MyBatis Plugin的设计与实现
MyBatis Plugin功能介绍
背景介绍
MyBatis Plugin

该思维导图由 AI 生成,仅供参考

上节课,我们对 MyBatis 框架做了简单的背景介绍,并且通过对比各种 ORM 框架,学习了代码的易用性、性能、灵活性之间的关系。一般来讲,框架提供的高级功能越多,那性能损耗就会越大;框架用起来越简单,提供越简化的使用方式,那灵活性也就越低。
接下来的两节课,我们再学习一下 MyBatis 用到一些经典设计模式。其中,今天,我们主要讲解 MyBatis Plugin。尽管名字叫 Plugin(插件),但它实际上跟之前讲到的 Servlet Filter(过滤器)、Spring Interceptor(拦截器)类似,设计的初衷都是为了框架的扩展性,用到的主要设计模式都是职责链模式。
不过,相对于 Servlet Filter 和 Spring Interceptor,MyBatis Plugin 中职责链模式的代码实现稍微有点复杂。它是借助动态代理模式来实现的职责链。今天我就带你看下,如何利用这两个模式实现 MyBatis Plugin。
话不多说,让我们正式开始今天的学习吧!

MyBatis Plugin 功能介绍

实际上,MyBatis Plugin 跟 Servlet Filter、Spring Interceptor 的功能是类似的,都是在不需要修改原有流程代码的情况下,拦截某些方法调用,在拦截的方法调用的前后,执行一些额外的代码逻辑。它们的唯一区别在于拦截的位置是不同的。Servlet Filter 主要拦截 Servlet 请求,Spring Interceptor 主要拦截 Spring 管理的 Bean 方法(比如 Controller 类的方法等),而 MyBatis Plugin 主要拦截的是 MyBatis 在执行 SQL 的过程中涉及的一些方法。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入介绍了如何利用职责链与代理模式实现MyBatis Plugin,并展示了其底层实现原理。通过一个例子演示了如何使用MyBatis Plugin来统计应用中每个SQL的执行耗时。文章详细介绍了SqlCostTimeInterceptor类的实现,以及在MyBatis的全局配置文件中声明插件的方法。此外,解释了@Intercepts注解和@Signature注解的作用,以及MyBatis Plugin默认允许拦截的方法。最后,指出了利用MyBatis Plugin还可以实现分库分表、自动分页、数据脱敏、加密解密等功能。整体而言,本文通过实际例子和详细解释,使读者能够快速了解MyBatis Plugin的功能和使用方法,以及其底层实现原理。文章还探讨了职责链模式和动态代理模式在MyBatis Plugin中的应用,以及与Servlet Filter和Spring Interceptor的区别。欢迎留言分享你的想法,以及将本文分享给你的朋友。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《设计模式之美》
新⼈⾸单¥98
立即购买
登录 后留言

全部留言(22)

  • 最新
  • 精选
  • test
    思考题:因为用mybatis就是为了使用数据库。
    2020-05-25
    34
  • Monday
    精彩,看了源码,Mybatis分布工具PageHelper也通过Plugin方式实现的。 @Intercepts({@Signature( type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class} )}) public class PageHelper implements Interceptor {...}
    2020-05-26
    27
  • your problem?
    思考题:YAGNI,单一职责原则,MyBatis就是负责简化以及通用数据库的处理,没有必要支持过多无关的东西
    2020-05-25
    20
  • 小晏子
    我感觉这要从mybatis的使用场景考虑,mybatis主要用于简化数据库操作,所以对于SQL语句的解析才是其本质,而不需要额外支持其他的东西,所以不需要拦截用户自定义类的方法
    2020-05-25
    11
  • J.Smile
    Springaop中的前置通知,后置通知,异常通知也是基于动态代理的职责链模式。
    2020-05-30
    9
  • Lambor
    MyBatis 每次SQL执行都会创建 Executor 等对象,再通过 pluginAll 方法创建一个代理的职责链,然后递归调用每个代理对象,最后调用 Executor 对象的方法。个人认为这个代理职责链主要就是控制 Executor 的方法在最后一步执行,这种职责链+代理的实现方式虽然巧妙,但感觉得不偿失,每次SQL调用都会创建一个新的嵌套代理调用链,这本身就是有性能消耗的,而且是作为底层框架,这点性能还是要考虑的。感觉采用 ApplicationFilterChain 的那种方式会更好,固定的一个拦截器链路,不用每次创建代理。
    2020-05-27
    2
    6
  • Monday
    看第一篇以为听懂了,再第二篇,发现根本没懂。如果换成是我要实现sql耗时的操作,走两步就行 1、写一个切面拦截StatementHander的某些方法,在执行sql前后加开始结束时间就行。 2、上一点中拦截哪些方法,还是需要一个类似Plugin中的getSignatureMap方法的解析,没感觉到Plugin类其他的价值。。
    2020-05-26
    1
    4
  • ljx
    感觉自己变强了,一年前看这段源码觉得云里雾里,只能理解个大概,如今再看是如此清晰。。。
    2022-03-11
    2
  • 高乐
    请问老师,动态代理后的代理类是final的吧,应该无法再次被动态代理吧?那这个嵌套代理是怎么实现的?
    2021-11-16
    2
  • Heaven
    职责单一,我用Mybatis就是为了更快更好的处理数据库之间的关系,所以专注于这四类是必然的,之前咱自己也看过Mybatis源码,但是并没有看出来是利用代理和职责链实现的整体执行过程
    2020-05-26
    2
收起评论
显示
设置
留言
22
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部