Plugin 实现了 InvocationHandler 接口,因此它的 invoke 方法会拦截所有的方法调用。
invoke 方法会对所拦截的方法进行检测,以决定是否执行插件逻辑。该方法的逻辑如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| // -☆- Plugin public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { // 获取被拦截方法列表,比如:signatureMap.get(Executor.class), // 可能返回 [query, update, commit] 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); } catch (Exception e) { throw ExceptionUtil.unwrapThrowable(e); } }
|
首先,invoke 方法会检测被拦截方法是否配置在插件的@Signature注解中,若是,则执行插件逻辑,否则执行被拦截方法。插件逻辑封装在 intercept 中,该方法的参数类型为 Invocation。
Invocation 主要用于存储目标类,方法以及方法参数列表。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 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 proceed() throws InvocationTargetException, IllegalAccessException { // 调用被拦截的方法 return method.invoke(target, args); } }
|