Mybatis拦截器的实现:
官方文档示例:https://mybatis.org/mybatis-3/zh/configuration.html#plugins
拦截器用到责任链模式+动态代理+反射机制,拦截器的使用可以在不侵入业务代码的场景下,进行一些数据权限过了、SQL执行时间和性能的监控等等。
- 自定义拦截器类:自定义的拦截器需要实现Interceptor接口,并且在自定义拦截器类上添加@Intercepts注解;
- 注册拦截器类:mybatis拦截器配置信息,将插件注册到全局配置文件中。
使用示例:
// ExamplePlugin.java
// @Intercepts 标识需要拦截器类
// @Signature指定需要拦截的方法签名
@Intercepts(
{@Signature(
// 需要拦截的目标对象
type= Executor.class,
// 指定拦截目标对象的方法
method = "update",
// 方法的参数
args = {MappedStatement.class,Object.class})
}
)
public class ExamplePlugin implements Interceptor {
// 拦截器的属性,插件注册时通过setProperties设置进来
private Properties properties = new Properties();
// 拦截目标对象Executor.update的方法被调用时执行拦截方法intercept
public Object intercept(Invocation invocation) throws Throwable {
// implement pre processing if need
// 执行目标方法
Object returnObject = invocation.proceed();
// implement post processing if need
return returnObject;
}
// 将插件注册时,会将property属性设置进来
public void setProperties(Properties properties) {
// 将属性配置存储在properties中
this.properties = properties;
}
}
<!-- mybatis-config.xml -->
// mybatis拦截器配置信息,将插件注册到全局配置文件中
<plugins>
// 通过类路路径来配置注册插件
<plugin interceptor="org.mybatis.example.ExamplePlugin">
// 属性配置
<property name="someProperty" value="100"/>
</plugin>
</plugins>
Mybatis可拦截的四大对象:
- Executor:Mybatis执行器,主要负责SQL语句的生成和执行;
- ParameterHandler:将用户传递的参数转换成JDBC Statement 所需要的参数;
- ResultHandler:将JDBC返回的ResultSet结果集对象转换成List类型的集合;
- StatementHandler:封装了JDBC Statement操作,负责对JDBC statement 的操作,如设置参数、将Statement结果集转换成List集合。
可拦截的类 |
可拦截的方法 |
Executor |
update, query, flushStatements, commit, rollback,getTransaction, close, isClosed |
ParameterHandler |
getParameterObject, setParameters |
ResultSetHandler |
handleResultSets, handleOutputParameters |
StatementHandler |
prepare, parameterize, batch, update, query |
1、在四大对象创建之后并不是直接返回,使用责任链模式,都是经过拦截器链interceptorChain.pluginAll()方法的调用,判断是否需要拦截来返回包装后的目标对象(新的动态代理对象);
2、使用拦截器会为目标对象创建一个代理对象,如果有N个拦截器,就会有N个代理对象