基本介绍
在MyBatis中,通过拦截器来实现插件,通过动态代理组织多个插件(拦截器),通过这些插件可以改变Mybatis的默认行为,如果你想做的不仅仅是监控方法的调用,那么你最好相当了解要重写的方法的行为。 因为在试图修改或重写已有方法的行为时,很可能会破坏 MyBatis 的核心模块。 这些都是更底层的类和方法,所以使用插件的时候要特别当心。MyBatis的插件通过拦截执行sql的四个接口来实现:Executor,StatementHandler, ResultSetHandler, ParameterHandler。
四大接口
插件Interceptor
Mybatis的插件实现要实现Interceptor接口。
1)Intercept:拦截目标方法执行;
2)plugin:生成动态代理对象;
3)注入插件配置时设置的属性
自定义插件
单个插件
需求:对org.apache.ibatis.executor.statement.StatementHandler 中的prepare 方法进行拦截
1)编写插件实现Interceptor接口,并使用@Intercepts注解完成插件签名
package com.fly.plugin;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.*;
import java.util.Properties;
/**
* @author 26414
*/
@Intercepts({
@Signature(type= StatementHandler.class,method="parameterize",args=java.sql.Statement.class)
})
public class MyPlugin implements Interceptor {
/**
* 拦截目标对象的目标方法的执行;
*/
@Override
public Object intercept(Invocation invocation) throws Throwable {
System.out.println("=========MyPlugin========");
return invocation.proceed();
}
/**
* 为目标对象创建一个代理对象
*/
@Override
public Object plugin(Object target) {
return Plugin.wrap(target,this);
}
/**
* 将插件注册时 的property属性设置进来
*/
@Override
public void setProperties(Properties properties) {
}
}
2)在全局配置文件中注册插件
<!--mybatis-config.xml-->
<plugins>
<plugin interceptor="com.fly.plugin.MyPlugin"/>
</plugins>
多个插件
package com.fly.plugin;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.*;
import java.util.Properties;
/**
* @author 26414
*/
@Intercepts({
@Signature(type= StatementHandler.class,method="parameterize",args=java.sql.Statement.class)
})
public class MySecondPlugin implements Interceptor {
/**
* 拦截目标对象的目标方法的执行;
*/
@Override
public Object intercept(Invocation invocation) throws Throwable {
System.out.println("=========MySecondPlugin========");
return invocation.proceed();
}
/**
* 为目标对象创建一个代理对象
*/
@Override
public Object plugin(Object target) {
return Plugin.wrap(target,this);
}
/**
* 将插件注册时 的property属性设置进来
*/
@Override
public void setProperties(Properties properties) {
}
}
<!--mybatis-config.xml-->
<plugins>
<plugin interceptor="com.fly.plugin.MyPlugin"/>
<plugin interceptor="com.fly.plugin.MySecondPlugin"/>
</plugins>
可以看到是第二个插件先执行的。
原理
1)按照插件注解声明,按照插件配置顺序调用插件plugin方法,生成被拦截对象的动态代理
2)多个插件依次生成目标对象的代理对象,层层包裹,先声明的先包裹;形成代理链
3)多个插件依次生成目标对象的代理对象,层层包裹,先声明的先包裹;形成代理链