0x00:前言参考 之前的《MyBatis 中 SqlMapConfig 配置文件详解》记了一下 MyBatis 中的核心配置文件各个标签的作用和使用场景,这篇文章细说一下配置文件中 plugins 标签的详细使用。 0x01:标签介绍 在某种情况下,需要在执行程序的过程中对某一点进行拦截,并在拦截后做出一系列处理,此时就需要使用一种拦截器。在 MyBatis 中,对某种方法进行拦截调用的机制,被称为 plugin 插件。使用 plugin 可以很好地对方法地调用进行监控,而且还可以修改或重写方法的行为逻辑。在 MyBatis 中允许使用 plugin 来拦截的方法如下: Executor(update,query,flushStatements,commit,rollback,getTransaction,close,isClosed) ParameterHandler(getParameterObject,setParameters) ResultSetHandler(handleResultSets,handleOutputParameters) StatementHandler(prepare,parameterize,batch,update,query) 其中,Executor 是 MyBatis 对外提供的一个操作接口类,其中包含了 query 查询、update 修改、commit 提交、rollback 回滚等核心方法。ParameterHandler、ResultSetHandler 及 StatementHandler 分别是处理参数、结果集、预编译状态的接口,里面的一些方法也可以使用 plugin 进行拦截。 0x02:代码示例 实现一个 plugin 只需要继承 Interceptor 接口,并且指定需要拦截的方法的签名信息即可。例如以下的示例: package cn.com.mybatis.test; import java.util.Properties; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.plugin.Intercepts; import org.apache.ibatis.plugin.Invocation; import org.apache.ibatis.plugin.Plugin; import org.apache.ibatis.plugin.Signature; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds; @Intercepts({ @Signature( type=Executor.class, method="query", args={MappedStatement.class,Object.class,RowBounds.class,ResultHandler.class} ) }) public class QueryPlugin implements Interceptor { public Object intercept(Invocation invocation) throws Throwable { return invocation.proceed(); } public Object plugin(Object target) { return Plugin.wrap(target,this); } public void setProperties(Properties arg0) {} } 类头部添加了 @Intercepts 拦截器注解,此注解声明此类是一个插件类。其中可以声明多个 @Signature 签名信息注解,type 为拦截的方法所属的接口类型,method 为拦截的方法名称,args 是参数信息。 intercept 方法是一个对目标方法进行拦截的抽象方法,而 plugin 方法的作用是将拦截器插入目标对象。 setProperties 方法的作用是将全局配置文件中的参数注入插件类中。 然后,在 MyBatis 全局配置文件中配置该插件即可,这样插件就会起到拦截作用,示例代码如下: <plugins> <plugin interceptor="cn.com.mybatis.test.QueryPlugin"> <property name="someProperty" value="100"/> </plugin> </plugins> 此时,就可以拦截 Executor 的 query 方法了,也就是默认执行的查询方法,可以在重写的插件类的 intercept 方法中添加拦截逻辑。 0x03:总结 插件使用的场景有:日志记录、权限控制、缓存控制等。使用 plugin 拦截和覆盖 MyBatis 的核心方法时,建议谨慎使用,否则会影响 MyBatis 的核心功能。