运行原理:
Mybatis 只⽀持针对
ParameterHandler
、
ResultSetHandler
、
StatementHandler
、
Executor
这
4
种接⼝的插件
Mybatis 使⽤ JDK 的动态代理, 为需要拦截的接⼝⽣成代理对象以实现接⼝⽅法拦截功能
每当执⾏这 4 种接⼝对象的⽅法时,就会进⼊拦截⽅法,具体就是 InvocationHandler 的 invoke()⽅法, 拦截那些你指定需要拦截的⽅法。
编写插件:
实现 Mybatis 的
Interceptor
接⼝并复写
intercept
()⽅法, 然后在给插件编写注解, 指定
要拦截哪⼀个接⼝的哪些⽅法即可, 在配置⽂件中配置编写的插件。
package com.tutu;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import java.lang.reflect.Method;
import java.util.Properties;
/**
* @Author: Hike
* @Date: 2022/8/6 12:45
* 你可以忘掉失败,但不能忘掉教训
* 注解声明mybatis当前插件拦截哪个对象的哪个方法
* type表示要拦截的目标对象 Executor.class StatementHandler.class ParameterHandler.class
ResultSetHandler.class
* method表示要拦截的方法,
* args表示要拦截方法的参数
*/
@Intercepts({
@Signature(type = Executor.class, method = "query",
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})
public class TestUpdateMybatisIntercepter implements Interceptor {
/**
* 拦截目标对象的目标方法执行
*
* @param invocation
* @return
* @throws Throwable
*/
@Override
public Object intercept(Invocation invocation) throws Throwable {
//被代理对象
Object target = invocation.getTarget();
//代理方法
Method method = invocation.getMethod();
//方法参数
Object[] args = invocation.getArgs();
// do something ...... 方法拦截前执行代码块
//执行原来方法
Object result = invocation.proceed();
// do something .......方法拦截后执行代码块
return result;
}
/**
* 包装目标对象:为目标对象创建代理对象
*
* @param target
* @return
*/
@Override
public Object plugin(Object target) {
System.out.println("MySecondPlugin为目标对象" + target + "创建代理对象");
//this表示当前拦截器,target表示目标对象,wrap方法利用mybatis封装的方法为目标对象创建代理对象(没有拦截的对象会直接返回,不会创建代理对象)
Object wrap = Plugin.wrap(target, this);
return wrap;
}
/**
* 设置插件在配置文件中配置的参数值
*
* @param properties
*/
@Override
public void setProperties(Properties properties) {
System.out.println(properties);
}
}
![](https://img-blog.csdnimg.cn/1d8a90867aa14e95a69df1e6c6afc2e2.png)