在编写插件时,除了需要让插件类实现 Interceptor 接口外,还需要通过注解标注

该插件的拦截点。所谓拦截点指的是插件所能拦截的方法,MyBatis 所允许拦截的方法如

下:

  1. Executor: update, query, flushStatements, commit, rollback,

    getTransaction, close, isClosed
  2. ParameterHandler: getParameterObject, setParameters
  3. ResultSetHandler: handleResultSets, handleOutputParameters
  4. StatementHandler: prepare, parameterize, batch, update, query

如果我们想要拦截 Executor 的 query 方法,那么可以这样定义插件

1
2
3
4
5
6
7
8
9
10
11
@Intercepts({
@Signature(
type = Executor.class,
method = "query",
args ={MappedStatement.class, Object.class, RowBounds.class,
ResultHandler.class}
)
})
public class ExamplePlugin implements Interceptor {
// 省略逻辑
}

除此之外,我们还需将插件配置到相关文件中。这样MyBatis在启动时可以加载插件,并保存插件实例到相关对象(InterceptorChain,拦截器链)中。

待准备工作做完后,MyBatis处于就绪状态。我们在执行SQL时,需要先通过DefaultSqlSessionFactory 创建SqlSession。Executor实例会在创建SqlSession的过程中被创建,Executor 实例创建完毕后,MyBatis会通过JDK动态代理为实例生成代理类。

这样,插件逻辑即可在Executor相关方法被调用前执行。以上就是MyBatis插件机制的基本原理。