前言
Mybatis通过InterceptorChain进行了很好的扩展。
一、InterceptorChain
public class InterceptorChain {
//拦截器
private final List<Interceptor> interceptors = new ArrayList<>();
//动态代理拦截器
public Object pluginAll(Object target) {
for (Interceptor interceptor : interceptors) {
target = interceptor.plugin(target);
}
return target;
}
//添加拦截器
public void addInterceptor(Interceptor interceptor) {
interceptors.add(interceptor);
}
public List<Interceptor> getInterceptors() {
return Collections.unmodifiableList(interceptors);
}
}
(1)、添加拦截器
在创建SqlSessionFactory的过程中,将插件存入InterceptorChain中
protected SqlSessionFactory buildSqlSessionFactory() throws Exception {
...
if (!isEmpty(this.plugins)) {
Stream.of(this.plugins).forEach(plugin -> {
targetConfiguration.addInterceptor(plugin);
LOGGER.debug(() -> "Registered plugin: '" + plugin + "'");
});
}
}
...
public void addInterceptor(Interceptor interceptor) {
interceptorChain.addInterceptor(interceptor);
}
(2)、使用拦截器
在mybatis的Configuration类中,对ParameterHandler 、ResultSetHandler 、StatementHandler 、Executor 进行增强,调用 interceptorChain.pluginAll( )方法。
public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql);
parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);
return parameterHandler;

本文详细介绍了Mybatis的拦截器InterceptorChain的实现原理,包括InterceptorChain如何添加和使用拦截器,以及Plugin的内部机制。通过Plugin类的代理方法和Signature注解,展示了如何自定义Interceptor来拦截特定方法。最后,给出一个TestInterceptor的例子,展示了如何拦截StatementHandler的prepare方法。总结中提到,拦截器的执行顺序与添加到链中的顺序相反。
最低0.47元/天 解锁文章
2万+

被折叠的 条评论
为什么被折叠?



