版权声明:本文为博主原创文章,未经博主允许,请勿转载。 https://blog.csdn.net/qq_36404323/article/details/85005158
拦截器
@Intercepts({@Signature(
type = StatementHandler.class,
method = "prepare",
args = {Connection.class, Integer.class}
)})
public class DataScopeInterceptor implements Interceptor {
public DataScopeInterceptor() {
}
public Object intercept(Invocation invocation) throws Throwable {
return invocation.proceed();
}
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
public void setProperties(Properties properties) {
}
}
拦截执行器原理
每个执行的对象都需要调用pluginAll方法使其被各个拦截器层层包裹(责任链模式),
包裹方式是在生成执行器前会使用jdk的动态代理借(Plugin implements InvocationHandler)类生成代理执行器,
InterceptorChain类:
public Object pluginAll(Object target) {
Interceptor interceptor;
for(Iterator var2 = this.interceptors.iterator(); var2.hasNext(); target = interceptor.plugin(target)) {
interceptor = (Interceptor)var2.next();
}
return target;
}
Plugin类:
public static Object wrap(Object target, Interceptor interceptor) {
Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor);
Class<?> type = target.getClass();
Class<?>[] interfaces = getAllInterfaces(type, signatureMap);
return interfaces.length > 0 ? Proxy.newProxyInstance(type.getClassLoader(), interfaces, new Plugin(target, interceptor, signatureMap)) : target;
}
Plugin类中的signatureMap保存了要拦截方法信息(拦截器@Signature所配置的方法信息),interceptor保存这个拦截器。
在调用执行器代理也就是Plugin类方法是时,会调用Plugin类的invoke方法,
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
Set<Method> methods = (Set)this.signatureMap.get(method.getDeclaringClass());
return methods != null && methods.contains(method) ? this.interceptor.intercept(new Invocation(this.target, method, args)) : method.invoke(this.target, args);
} catch (Exception var5) {
throw ExceptionUtil.unwrapThrowable(var5);
}
}
首先判断方法是否应该被拦截,需要拦截的话拦截器进行拦截并处理。