序
本文主要研究一下mybatis的Interceptor机制
Interceptor
org/apache/ibatis/plugin/Interceptor.java
public interface Interceptor {
Object intercept(Invocation invocation) throws Throwable;
default Object plugin(Object target) {
return Plugin.wrap(target, this);
}
default void setProperties(Properties properties) {
// NOP
}
}
Interceptor定义了intercept方法,其参数为Invocation类型,同时默认提供了plugin方法,通过Plugin.wrap(target, this)进行包装
Invocation
org/apache/ibatis/plugin/Invocation.java
public class Invocation {
private final Object target;
private final Method method;
private final Object[] args;
public Invocation(Object target, Method method, Object[] args) {
this.target = target;
this.method = method;
this.args = args;
}
public Object getTarget() {
return target;
}
public Method getMethod() {
return method;
}
public Object[] getArgs() {
return args;
}
public Object proceed() throws InvocationTargetException, IllegalAccessException {
return method.invoke(target, args);
}
}
Invocation定义了target、method、args属性,提供了proceed方法则是反射执行method方法
Plugin
org/apache/ibatis/plugin/Plugin.java
public class Plugin implements InvocationHandler {
private final Object target;
private final Interceptor interceptor;
private final Map<Class<?>, Set<Method>> signatureMap;
private Plugin(Object target, Interceptor interceptor, Map<Class<?>, Set<Method>> signatureMap) {
this.target = target;
this.interceptor = interceptor;
this.signatureMap = signatureMap;
}
public static Object wrap(Object target, Interceptor interceptor) {
Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor);
Class<?> type = target.getClass();
Class<?>[] interfaces = getAllInterfaces(type, signatureMap);
if (interfaces.length > 0) {
return Proxy.newProxyInstance(type.getClassLoader(), interfaces, new Plugin(target, interceptor, signatureMap));
}
return target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
Set<Method> methods = signatureMap.get(method.getDeclaringClass());
if (methods != null && methods.contains(method)) {
return interceptor.intercept(new Invocation(target, method, args));
}
return method.invoke(target, args);
} catc

本文详细解析了MyBatis中的Interceptor接口及其工作原理,包括Invocation、Plugin的包装与调用,以及如何在Spring集成中通过XML配置和自动配置类注册Interceptor,实现对SQL执行过程的拦截。
最低0.47元/天 解锁文章
1230

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



