全部学科
Python全栈
python
NodeJS全栈
nodejs
📝 1 篇文章 10 道配套习题

插件开发高级应用专题

专题说明

本专题系统讲解MyBatis插件机制的核心原理与高级应用,涵盖JDK动态代理构建的代理链机制、多插件执行顺序、分页插件深度定制、数据脱敏插件、SQL审计日志插件等完整实战场景。

学习目标

  1. 理解MyBatis插件的JDK动态代理机制与代理链构建原理
  2. 掌握多插件执行顺序与invocation.proceed()的短路机制
  3. 学会开发支持多数据库方言的分页插件
  4. 掌握数据脱敏插件在ResultSetHandler和TypeHandler层面的实现
  5. 理解SQL审计日志插件的异步写入与敏感信息处理

学习内容

  • 插件代理链原理:Plugin.wrap()、JDK动态代理、责任链模式
  • 多插件执行顺序:XML配置顺序与intercept调用顺序的关系
  • 分页插件深度定制:Executor拦截、SQL改写、多数据库方言
  • 数据脱敏插件:@Sensitive注解、ResultSetHandler拦截、TypeHandler实现
  • SQL审计日志插件:异步写入、敏感信息脱敏、批量写入

学习建议

MyBatis插件机制是框架的核心扩展点,建议结合源码理解Plugin.wrap()的代理链构建过程。分页插件是实战中最常见的自定义插件类型,数据脱敏和审计日志插件是生产环境的典型需求。

📝 配套习题(10 题)

💡 参考答案在文末
判断题
1

在 MyBatis 插件的 Plugin.wrap() 方法中,如果被代理对象已经是代理对象(即已经被前面的插件包装过),则不会再次创建新的代理,而是直接返回原有代理对象。()

A

B

单选题
2

在 MyBatis 插件开发中,关于插件代理链(Plugin Chain)的执行机制,以下说法正确的是?

A

多个插件按照配置的顺序依次执行,每个插件独立拦截目标方法

B

多个插件会形成责任链,后一个插件的 invocation.proceed() 会调用下一个插件的 intercept 方法

C

插件代理链中,所有插件的 intercept 方法会被同时并发调用

D

插件代理链只能拦截 Executor 接口,无法拦截 StatementHandler 等其他接口

3

在开发 MyBatis 自定义分页插件时,以下哪种方案是实现分页功能最合理的做法?

A

拦截 ResultSetHandler.handleResultSets() 方法,在结果集返回后截取指定范围的数据

B

拦截 Executor.query() 方法,改写 SQL 添加 LIMIT 子句,并同时执行 COUNT 查询获取总数

C

在 Mapper 接口方法中手动拼接 LIMIT 子句,不使用插件机制

D

拦截 StatementHandler.prepare() 方法,修改 Connection 的 autoCommit 属性来实现分页

多选题
4

在 MyBatis 配置文件 mybatis-config.xml 中按顺序配置了三个插件:

XML
<plugins>
    <plugin interceptor="com.example.PluginA"/>
    <plugin interceptor="com.example.PluginB"/>
    <plugin interceptor="com.example.PluginC"/>
</plugins>

关于这三个插件的执行顺序,以下说法正确的有哪些?

A

拦截 Executor.query 方法时,intercept 方法的调用顺序是 PluginA -> PluginB -> PluginC

B

拦截 Executor.query 方法时,intercept 方法的调用顺序是 PluginC -> PluginB -> PluginA

C

如果在 PluginB 的 intercept 方法中不调用 invocation.proceed(),则 PluginC 不会被执行

D

三个插件的 intercept 方法会按照 XML 配置顺序同时并发执行

5

在设计 MyBatis 数据脱敏插件时,以下哪些场景适合通过插件实现敏感数据的自动脱敏处理?

A

拦截 ResultSetHandler.handleResultSets(),在结果映射后对包含 @Sensitive 注解的字段进行脱敏

B

拦截 ParameterHandler.setParameters(),对传入的查询参数中的敏感信息进行加密

C

拦截 Executor.update(),对 INSERT/UPDATE 语句中的敏感字段值进行自动加密存储

D

在 TypeHandler 层面实现字符串类型的统一脱敏转换

6

开发 MyBatis SQL 审计日志插件时,以下哪些做法是正确的?

A

使用异步方式写入审计日志,避免阻塞正常业务 SQL 的执行

B

在拦截 Executor.update() 时,记录完整的 SQL 语句、参数值、执行耗时和操作人信息

C

使用 ThreadLocal 在请求入口处设置操作人信息,在插件中读取并写入审计日志

D

将审计日志直接 INSERT 到与业务相同的数据库中,共用同一个事务

填空题
7

假设 MyBatis 配置了两个插件:PluginX 和 PluginY(按此顺序配置)。当调用被代理的 Executor.query() 方法时,完整的调用链路为:

外部调用 query() -> ____________.intercept(invocation) -> invocation.proceed() -> ____________.intercept(invocation) -> invocation.proceed() -> 真实的 Executor.query()

请填写空白处的插件名称。

8

实现手机号脱敏工具方法,规则为:保留前 3 位和后 4 位,中间用 4 个 * 替换。例如 13812345678 脱敏后为 138****5678。

请补全以下代码:

Java
public static String maskPhone(String phone) {
    if (phone == null || phone.length() != !!1_11!!) {
        return phone;
    }
    return phone.substring(0, 3) + "____________" + phone.substring(phone.length() - !!3_4!!);
}
简答题
9

请设计一个支持多数据库方言(MySQL、Oracle、PostgreSQL)的分页插件的核心逻辑。要求:

  1. 说明拦截哪个接口的方法
  2. 如何处理不同数据库的分页 SQL 语法差异
  3. 如何同时获取总记录数
  4. 如何保证分页参数的正确传递
10

请设计一个生产级别的 SQL 审计日志插件,要求回答以下问题:

  1. 应该拦截哪些 MyBatis 接口和方法?为什么?
  2. 如何在记录 SQL 参数的同时避免日志中打印敏感信息(如密码明文)?
  3. 审计日志的数据结构应包含哪些核心字段?
  4. 在高并发场景下,如何保证审计日志的写入性能?
参考答案
1.错误 2.B 3.B 4.A;C 5.A;B;D 6.A;B;C 7.PluginX;PluginY 8.11;****;4 9. 10.
想在手机上练习这套专题?
使用微信卷王开发者小程序,打开首页顶部扫码功能识别二维码
← 上一个专题 接口绑定与动态代理专题
下一个专题 → 插件机制专题
扫码体验小程序
加载中
想在手机上刷题学习?
使用微信卷王开发者小程序,打开首页顶部扫码功能识别二维码