请解释 MyBatis 中拦截器(插件)机制的工作流程,并说明实现一个自定义拦截器需要哪些步骤?
考察说明
考查对 MyBatis 插件机制的理解及自定义插件开发流程的掌握程度。
回答思路
- 【回答框架 1】MyBatis 插件基于 JDK 动态代理实现,允许拦截四大核心对象:Executor、StatementHandler、ParameterHandler 和 ResultSetHandler。在创建这些对象时,MyBatis 会遍历所有注册的拦截器,通过 Plugin.wrap 方法生成代理对象,将拦截逻辑织入。
- 【回答框架 2】自定义插件需实现 Interceptor 接口,包含 intercept、plugin 和 setProperties 三个方法。intercept 方法编写核心拦截逻辑,通过 Invocation.proceed 调用原方法;plugin 方法决定是否包装目标对象;setProperties 用于读取配置参数。
- 【回答框架 3】在 intercept 方法中,可通过 invocation.getTarget() 获取目标对象,invocation.getArgs() 获取方法参数,invocation.getMethod() 获取方法。实现增强时需避免递归代理和循环调用,确保 proceed 正确执行。
- 【回答框架 4】编写完成后,需在 MyBatis 配置文件中通过 <plugins> 标签注册插件,并可选配置属性。同时注意拦截点应针对四大对象,否则代理不会生效。
- 【关键点 1】插件基于 JDK 动态代理,拦截四大核心对象。
- 【关键点 2】实现 Interceptor 接口,重写 intercept、plugin、setProperties 方法。
- 【关键点 3】在 configuration 中注册插件,代理对象在创建时生成。
- 【易错点 1】容易在 plugin 方法中直接返回目标对象,导致代理失效。
- 【易错点 2】拦截非四大对象无法生效。
- 【易错点 3】proceed 调用被跳过导致链路中断。