Skip to content

Commit 4477c4b

Browse files
committed
Interceptor optimization mybatis#1993
1 parent ac246c3 commit 4477c4b

File tree

2 files changed

+47
-16
lines changed

2 files changed

+47
-16
lines changed

src/main/java/org/apache/ibatis/plugin/Invocation.java

+15-4
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
*/
1616
package org.apache.ibatis.plugin;
1717

18-
import java.lang.reflect.InvocationTargetException;
1918
import java.lang.reflect.Method;
19+
import java.util.List;
2020

2121
/**
2222
* @author Clinton Begin
@@ -26,11 +26,15 @@ public class Invocation {
2626
private final Object target;
2727
private final Method method;
2828
private final Object[] args;
29+
private final List<Interceptor> interceptors;
30+
private int index;
2931

30-
public Invocation(Object target, Method method, Object[] args) {
32+
public Invocation(Object target, Method method, Object[] args, List<Interceptor> interceptors) {
3133
this.target = target;
3234
this.method = method;
3335
this.args = args;
36+
this.interceptors = interceptors;
37+
index = interceptors.size();
3438
}
3539

3640
public Object getTarget() {
@@ -45,8 +49,15 @@ public Object[] getArgs() {
4549
return args;
4650
}
4751

48-
public Object proceed() throws InvocationTargetException, IllegalAccessException {
49-
return method.invoke(target, args);
52+
public Object proceed() throws Throwable {
53+
54+
if ((index--) == 0) {
55+
return method.invoke(target, args);
56+
}
57+
58+
Interceptor interceptor = interceptors.get(index);
59+
return interceptor.intercept(this);
60+
5061
}
5162

5263
}

src/main/java/org/apache/ibatis/plugin/Plugin.java

+32-12
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
import java.lang.reflect.InvocationHandler;
1919
import java.lang.reflect.Method;
2020
import java.lang.reflect.Proxy;
21+
import java.util.ArrayList;
2122
import java.util.HashMap;
2223
import java.util.HashSet;
24+
import java.util.List;
2325
import java.util.Map;
2426
import java.util.Set;
2527

@@ -31,41 +33,59 @@
3133
public class Plugin implements InvocationHandler {
3234

3335
private final Object target;
34-
private final Interceptor interceptor;
35-
private final Map<Class<?>, Set<Method>> signatureMap;
36+
private final Map<Method, List<Interceptor>> interceptorMap;
3637

37-
private Plugin(Object target, Interceptor interceptor, Map<Class<?>, Set<Method>> signatureMap) {
38+
private Plugin(Object target, Map<Method, List<Interceptor>> interceptorMap) {
3839
this.target = target;
39-
this.interceptor = interceptor;
40-
this.signatureMap = signatureMap;
40+
this.interceptorMap = interceptorMap;
41+
}
42+
43+
public Map<Method, List<Interceptor>> getInterceptorMap() {
44+
return interceptorMap;
4145
}
4246

4347
public static Object wrap(Object target, Interceptor interceptor) {
4448
Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor);
4549
Class<?> type = target.getClass();
4650
Class<?>[] interfaces = getAllInterfaces(type, signatureMap);
4751
if (interfaces.length > 0) {
48-
return Proxy.newProxyInstance(
49-
type.getClassLoader(),
50-
interfaces,
51-
new Plugin(target, interceptor, signatureMap));
52+
if (Proxy.isProxyClass(target.getClass())) {
53+
InvocationHandler invocationHandler = Proxy.getInvocationHandler(target);
54+
if (invocationHandler instanceof Plugin) {
55+
Map<Method, List<Interceptor>> interceptorMap = ((Plugin) invocationHandler).getInterceptorMap();
56+
mapping(interceptor, signatureMap, interceptorMap);
57+
return target;
58+
}
59+
}
60+
61+
Map<Method, List<Interceptor>> interceptorMap = new HashMap<>();
62+
mapping(interceptor, signatureMap, interceptorMap);
63+
return Proxy.newProxyInstance(type.getClassLoader(), interfaces, new Plugin(target, interceptorMap));
5264
}
5365
return target;
5466
}
5567

5668
@Override
5769
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
5870
try {
59-
Set<Method> methods = signatureMap.get(method.getDeclaringClass());
60-
if (methods != null && methods.contains(method)) {
61-
return interceptor.intercept(new Invocation(target, method, args));
71+
List<Interceptor> interceptors = interceptorMap.get(method);
72+
if (interceptors != null) {
73+
return new Invocation(target, method, args, interceptors).proceed();
6274
}
6375
return method.invoke(target, args);
6476
} catch (Exception e) {
6577
throw ExceptionUtil.unwrapThrowable(e);
6678
}
6779
}
6880

81+
private static void mapping(Interceptor interceptor, Map<Class<?>, Set<Method>> signatureMap, Map<Method, List<Interceptor>> interceptorMap) {
82+
for (Set<Method> methods : signatureMap.values()) {
83+
for (Method method : methods) {
84+
interceptorMap.computeIfAbsent(method, (key) -> new ArrayList<>()).add(interceptor);
85+
}
86+
}
87+
}
88+
6989
private static Map<Class<?>, Set<Method>> getSignatureMap(Interceptor interceptor) {
7090
Intercepts interceptsAnnotation = interceptor.getClass().getAnnotation(Intercepts.class);
7191
// issue #251

0 commit comments

Comments
 (0)