当前位置: 首页 > news >正文

七、插件机制

Interceptor

MyBatis 插件模块中最核心的接口就是 Interceptor 接口,它是所有 MyBatis 插件必须要实现的接口,其核心定义如下:

public interface Interceptor {// 插件实现类中需要实现的拦截逻辑Object intercept(Invocation invocation) throws Throwable;// 在该方法中会决定是否触发intercept()方法default Object plugin(Object target) {return Plugin.wrap(target, this);}default void setProperties(Properties properties) {// 在整个MyBatis初始化过程中用来初始化该插件的方法}}

MyBatis允许我们自定义 Interceptor 拦截 SQL 语句执行过程中的某些关键逻辑,允许拦截的方法有:Executor 类中的 update()、query()、flushStatements()、commit()、rollback()、getTransaction()、close()、isClosed()方法,ParameterHandler 中的 setParameters()、getParameterObject() 方法,ResultSetHandler中的 handleOutputParameters()、handleResultSets()方法,以及StatementHandler 中的parameterize()、prepare()、batch()、update()、query()方法。

自定义的插件

@Intercepts({@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class,ResultHandler.class}),@Signature(type = Executor.class, method = "close", args = {boolean.class})
})
public class DemoPlugin implements Interceptor {private int logLevel; ... // 省略其他方法的实现
}

我们看到 DemoPlugin 这个示例类除了实现 Interceptor 接口外,还被标注了 @Intercepts 和 @Signature 两个注解。@Intercepts 注解中可以配置多个 @Signature 注解,@Signature 注解用来指定 DemoPlugin 插件实现类要拦截的目标方法信息,其中的 type 属性指定了要拦截的类,method 属性指定了要拦截的目标方法名称,args 属性指定了要拦截的目标方法的参数列表。通过 @Signature 注解中的这三个配置,DemoPlugin 就可以确定要拦截的目标方法的方法签名。在上面的示例中,DemoPlugin 会拦截 Executor 接口中的 query(MappedStatement, Object, RowBounds, ResultHandler) 方法和 close(boolean) 方法。

完成 DemoPlugin 实现类的编写之后,为了让 MyBatis 知道这个类的存在,我们要在 mybatis-config.xml 全局配置文件中对 DemoPlugin 进行配置,相关配置片段如下:

<plugins><plugin interceptor="design.Interceptor.DemoPlugin"><!-- 对拦截器中的属性进行初始化 --><property name="logLevel" value="1"/></plugin>
</plugins>

InterceptorChain

MyBatis 中 Executor、ParameterHandler、ResultSetHandler、StatementHandler 等与 SQL 执行相关的核心组件都是通过 Configuration.new*() 方法生成的。以 newExecutor() 方法为例,我们会看到下面这行代码,InterceptorChain.pluginAll() 方法会为目标对象(也就是这里的 Executor 对象)创建代理对象并返回。

executor = (Executor) interceptorChain.pluginAll(executor);
public Object pluginAll(Object target) {for (Interceptor interceptor : interceptors) {// 遍历interceptors集合,调用每个Interceptor对象的plugin()方法target = interceptor.plugin(target);}return target;
}

Plugin

从 DemoPlugin 示例中,我们可以看到 plugin() 方法依赖 MyBatis 提供的 Plugin.wrap() 工具方法创建代理对象

MyBatis 提供的 Plugin 工具类实现了 JDK 动态代理中的 InvocationHandler 接口,同时维护了下面三个关键字段。

  • target(Object 类型):要拦截的目标对象。
  • signatureMap(Map<Class<?>, Set> 类型):记录了 @Signature 注解中配置的方法信息,也就是代理要拦截的目标方法信息。
  • interceptor(Interceptor 类型):目标方法被拦截后,要执行的逻辑就写在了该 Interceptor 对象的 intercept() 方法中。

在 invoke() 方法中,Plugin 会检查当前要执行的方法是否在 signatureMap 集合中,如果在其中的话,表示当前待执行的方法是我们要拦截的目标方法之一,也就会调用 intercept() 方法执行代理逻辑;如果未在其中的话,则表示当前方法不应被代理,直接执行当前的方法即可。下面就是 Plugin.invoke() 方法的核心实现:

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {try {// 获取当前类被拦截的方法Set<Method> methods = signatureMap.get(method.getDeclaringClass());// 如果当前方法需要被代理,则执行intercept()方法进行拦截处理if (methods != null && methods.contains(method)) {return interceptor.intercept(new Invocation(target, method, args));}return method.invoke(target, args);} catch (Exception e) {throw ExceptionUtil.unwrapThrowable(e);}}

相关文章:

七、插件机制

Interceptor MyBatis 插件模块中最核心的接口就是 Interceptor 接口&#xff0c;它是所有 MyBatis 插件必须要实现的接口&#xff0c;其核心定义如下&#xff1a; public interface Interceptor {// 插件实现类中需要实现的拦截逻辑Object intercept(Invocation invocation) …...

kmp算法

前缀函数 π[i]max⁡k0,⋯,i{k∣s[0,⋯,k−1]s[i−(k−1),⋯,i]}\pi\left[i\right] \max\limits_{k 0,\cdots, i}\left\{k|s\left[0,\cdots,k-1\right] s\left[i-\left(k-1\right) ,\cdots, i\right]\right\} π[i]k0,⋯,imax​{k∣s[0,⋯,k−1]s[i−(k−1),⋯,i]} 简单来说…...

【Python】正则表达式简单教程

0x01 正则表达式概念及符号含义 掌握正则表达式&#xff0c;只需要记住不同符号所表示的含义&#xff0c;以及对目标对象模式&#xff08;或规律&#xff09;的正确概括。 1、基础内容 字符匹配 在正则表达式中&#xff0c;如果直接给出字符&#xff0c;就是精确匹配。\d 匹…...

SAP ABAP Odata

GetEntity和GetEntitys GetEntitys 创建Odata Project 导入结构 选择需要的字段 设定Key 勾选字段的creatable、updatable、sortable、nullable、filterable属性值。 再依上述步骤创建ZPOITEM结构和实体集 3. 创建ZPOHEADER和ZPOITEM的Association 两个实体集的关联字段&…...

Android native ASAN 排查内存泄漏

一、概述 android 对native - c/c 的调试和排查是比较难受的一件事。我看周遭做window &#xff0c; linux 甚至ios的调试排查起c的代码都比较方便。习惯了app开发去熟悉native是各种痛苦&#xff0c;最主要是排查问题上。后续有时间打算整理下native 的错误排查使用&#xff…...

Django项目开发

一.认识NoSQL 1.SQL 关系型数据库 结构化: 定义主键&#xff0c;无符号型数据等关联的&#xff1a;结构化表和表之间的关系通过外键进行关联&#xff0c;节省存储空间SQL查询&#xff1a;语法固定 SELECT id,name,age FROM tb_user WHERE id1 ACID 2.NoSQL 非关系型数据库 Re…...

Debezium系列之:深入理解Debezium Server和Debezium Server实际应用案例详解

Debezium系列之:深入理解Debezium Server和Debezium Server实际应用案例详解 一、认识Debezium Server二、下载Debezium Server三、解压Debezium Server四、查看Debezium Server目录五、Debezium Server配置六、Debezium Server启动输出样式七、源配置八、格式配置九、Transfo…...

IDE2022源码编译tomcat

因为学习需要&#xff0c;我需要源码编译运行tomcat对其源码进行一个简单的追踪分析。由于先前并未接触过java相关的知识&#xff0c;安装阻力巨大。最后请教我的开发朋友才解决了最后的问题。将其整理出来&#xff0c;让大家能够快速完成相关的部署。本文仅解决tomcat-8.5.46版…...

214 情人节来袭,电视剧 《点燃我温暖你》李峋同款 Python爱心表白代码,赶紧拿去用吧

大家好&#xff0c;我是徐公&#xff0c;六年大厂程序员经验&#xff0c;今天为大家带来的是动态心形代码&#xff0c;电视剧 《点燃我温暖你》同款的&#xff0c;大家赶紧看看&#xff0c;拿去向你心仪的对象表白吧&#xff0c;下面说一下灵感来源。 灵感来源 今天&#xff…...

数据库范式

基本概念 函数依赖 x→yx\rightarrow yx→y&#xff0c;当确定xxx的时候&#xff0c;yyy也可以确定 例&#xff1a; 学号→\rightarrow→姓名&#xff0c;当知道了学号&#xff0c;就知道了学生姓名 学号,课程号→\rightarrow→成绩&#xff0c;当知道了学号和课程号&#xff…...

CUDA中的底层驱动API

文章目录CUDA底层驱动API1. Context2. Module3. Kernel Execution4. Interoperability between Runtime and Driver APIs5. Driver Entry Point Access5.1. Introduction5.2. Driver Function Typedefs5.3. Driver Function Retrieval5.3.1. Using the driver API5.3.2. Using …...

【博客616】prometheus staleness对PromQL查询的影响

prometheus staleness对PromQL查询的影响 1、prometheus staleness 官方文档的解释&#xff1a; 概括&#xff1a; 运行查询时&#xff0c;将独立于实际的当前时间序列数据选择采样数据的时间戳。这主要是为了支持聚合&#xff08;sum、avg 等&#xff09;等情况&#xff0c…...

多传感器融合定位十三-基于图优化的建图方法其二

多传感器融合定位十二-基于图优化的建图方法其二3.4 预积分方差计算3.4.1 核心思路3.4.2 连续时间下的微分方程3.4.3 离散时间下的传递方程3.5 预积分更新4. 典型方案介绍4.1 LIO-SAM介绍5. 融合编码器的优化方案5.1 整体思路介绍5.2 预积分模型设计Reference: 深蓝学院-多传感…...

linux 服务器线上问题故障排查

一 线上故障排查概述 1.1 概述 线上故障排查一般从cpu,磁盘,内存,网络这4个方面入手; 二 磁盘的排查 2.1 磁盘排查 1.使用 df -hl 命令来查看磁盘使用情况 2.从读写性能排查:iostat -d -k -x命令来进行分析 最后一列%util可以看到每块磁盘写入的程度,而rrqpm/s以及…...

Sandman:一款基于NTP协议的红队后门研究工具

关于Sandman Sandman是一款基于NTP的强大后门工具&#xff0c;该工具可以帮助广大研究人员在一个安全增强型网络系统中执行红队任务。 Sandman可以充当Stager使用&#xff0c;该工具利用了NTP&#xff08;一个用于计算机时间/日期同步协议&#xff09;从预定义的服务器获取并…...

【SSL/TLS】准备工作:HTTPS服务器部署:Nginx部署

HTTPS服务器部署&#xff1a;Nginx部署1. 准备工作2. Nginx服务器YUM部署2.1 直接安装2.2 验证3. Nginx服务器源码部署3.1 下载源码包3.2 部署过程4. Nginx基本操作4.1 nginx常用命令行4.2 nginx重要目录1. 准备工作 1. Linux版本 [rootlocalhost ~]# cat /proc/version Li…...

微搭低代码从入门到精通11-数据模型

学习微搭低代码&#xff0c;先学习基本操作&#xff0c;然后学习组件的基本使用。解决了前端的问题&#xff0c;我们就需要深入学习后端的功能。后端一般包括两部分&#xff0c;第一部分是常规的数据库的操作&#xff0c;包括增删改查。第二部分是业务逻辑的编写&#xff0c;在…...

【算法基础】前缀和与差分

&#x1f63d;PREFACE&#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐ 评论&#x1f4dd;&#x1f4e2;系列专栏&#xff1a;算法&#x1f4aa;种一棵树最好是十年前其次是现在1.什么是前缀和前缀和指一个数组的某下标之前的所有数组元素的和&#xff08;包含其自身&#x…...

LTD212次升级 | 官网社区支持PC端展示 • 官网新增证件查询应用,支持条形码扫码查询

1、新增证件查询应用&#xff0c;支持条形码扫码查询&#xff1b; 2、新增用户社区PC端功能&#xff1b; 01证件查询应用 1、新增证件查询应用功能 支持证件信息录入、打印功能&#xff0c;支持条形码扫码识别。 后台管理操作路径&#xff1a;官微中心 - 应用 - 证件查询 …...

【安全】nginx反向代理+负载均衡上传webshell

目录 一、负载均衡反向代理下上传webshell Ⅰ、环境搭建 ①下载蚁剑&#xff0c;于github获取官方版&#xff1a; ②下载docker&docker-compose ③结合前面启动环境 ④验证 负载均衡下webshell上传 一、负载均衡反向代理下上传webshell 什么是反向代理&#xff1f; 通常的代…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...

消息队列系统设计与实践全解析

文章目录 &#x1f680; 消息队列系统设计与实践全解析&#x1f50d; 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡&#x1f4a1; 权衡决策框架 1.3 运维复杂度评估&#x1f527; 运维成本降低策略 &#x1f3d7;️ 二、典型架构设计2.1 分布式事务最终一致…...

自然语言处理——文本分类

文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益&#xff08;IG&#xff09; 分类器设计贝叶斯理论&#xff1a;线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别&#xff0c; 有单标签多类别文本分类和多…...