简述 MyBatis 的插件运行原理以及如何编写一个插件
2025年Java面试宝典抢先领:
🔗 链接: https://pan.baidu.com/s/1RUVf75gmDVsg8MQp4yRChg?pwd=9b3g
🔑 提取码:9b3g(建议保存备用)
一、MyBatis 插件运行原理(拦截器机制)
MyBatis 插件本质上是一个拦截器,基于 JDK 动态代理和责任链模式实现。它的核心原理可概括为三步:
-
拦截点识别
MyBatis 在四大核心对象中预留了插件扩展点:Executor(执行器):拦截 SQL 执行全过程ParameterHandler(参数处理器):拦截参数处理ResultSetHandler(结果集处理器):拦截结果集映射StatementHandler(语句处理器):拦截 SQL 编译
-
动态代理包装

当 MyBatis 启动时,会遍历所有注册的插件,通过动态代理技术对上述四个对象生成代理。调用目标方法时,代理会先执行插件的intercept()方法。 -
责任链调用
多个插件会形成拦截器链(InterceptorChain)。调用顺序由配置顺序决定,通过Invocation.proceed()触发链式执行,最终调用原始方法。
二、编写 MyBatis 插件的 3 个关键步骤
步骤1:实现 Interceptor 接口
自定义类需实现 org.apache.ibatis.plugin.Interceptor 接口,核心是重写三个方法:
public class MyPlugin implements Interceptor {
// 1. 拦截逻辑入口
@Override
public Object intercept(Invocation invocation) throws Throwable {
// 前置处理 (例如: SQL日志打印)
Object result = invocation.proceed(); // 执行原方法
// 后置处理 (例如: 结果集加密)
return result;
}
// 2. 生成目标对象的代理
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
// 3. 读取插件配置参数
@Override
public void setProperties(Properties properties) {
String param = properties.getProperty("key");
}
}
步骤2:通过 @Intercepts 声明拦截点
使用注解精确指定要拦截的方法签名:
@Intercepts({
@Signature(
type = StatementHandler.class, // 目标类
method = "prepare", // 方法名
args = {Connection.class, Integer.class} // 参数类型
)
})
public class SqlMonitorPlugin implements Interceptor {...}
步骤3:在配置文件中注册插件
在 mybatis-config.xml 中添加配置:
<plugins>
<plugin interceptor="com.example.MyPlugin">
<property name="threshold" value="500"/> <!-- 自定义参数 -->
</plugin>
</plugins>
三、典型插件应用场景
- SQL 性能监控:统计执行时间,自动告警慢查询
- 分页功能增强:统一改造
limit语法 - 数据权限控制:动态追加 WHERE 条件
- 敏感数据脱敏:结果集字段加密/遮挡
- SQL 日志美化:格式化输出到控制台
💡 面试技巧提示:
当被问到 MyBatis 插件原理 时,重点突出 动态代理 + 责任链 的设计思想。可举例说明:“比如我们开发一个分页插件,实际上是在StatementHandler.prepare()阶段重写了原始 SQL”。
最后的小福利
如果你正在准备 Java 面试,强烈推荐使用 面试鸭返利网 开通面试鸭会员!
👉 专属返利通道:mianshiyafanli.com
📢 通过此链接购买可返现 25 元,相当于会员价直接打折!
(提示:购买后联系客服提供订单号即可领取返利)

高效备战面试,从精准刷题开始
本文已收录到《MyBatis 高阶面试指南》,更多深度技术解析可访问:
🔗 面试鸭返利网 - 程序员备考平台


