Skip to content

Commit 15119ec

Browse files
committed
try to optimize according to the hint
1 parent c263f20 commit 15119ec

File tree

2 files changed

+45
-17
lines changed

2 files changed

+45
-17
lines changed

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

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,16 @@ public class Invocation {
3535
private final Object target;
3636
private final Method method;
3737
private final Object[] args;
38+
private final List<Interceptor> interceptors;
3839

39-
public Invocation(Object target, Method method, Object[] args) {
40+
public Invocation(Object target, Method method, Object[] args, List<Interceptor> interceptors) {
4041
if (!targetClasses.contains(method.getDeclaringClass())) {
4142
throw new IllegalArgumentException("Method '" + method + "' is not supported as a plugin target.");
4243
}
4344
this.target = target;
4445
this.method = method;
4546
this.args = args;
47+
this.interceptors = interceptors;
4648
}
4749

4850
public Object getTarget() {
@@ -57,8 +59,14 @@ public Object[] getArgs() {
5759
return args;
5860
}
5961

60-
public Object proceed() throws InvocationTargetException, IllegalAccessException {
61-
return method.invoke(target, args);
62+
public Object proceed() throws Throwable {
63+
int intSize = interceptors.size();
64+
if ((intSize --)== 0) {
65+
return method.invoke(target, args);
66+
}
67+
Interceptor interceptor = interceptors.get(intSize);
68+
return interceptor.intercept(this);
69+
6270
}
6371

6472
}

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

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,52 +18,72 @@
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;
25-
2627
import org.apache.ibatis.reflection.ExceptionUtil;
27-
import org.apache.ibatis.util.MapUtil;
28+
2829

2930
/**
3031
* @author Clinton Begin
3132
*/
3233
public class Plugin implements InvocationHandler {
3334

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

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

4447
public static Object wrap(Object target, Interceptor interceptor) {
4548
Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor);
4649
Class<?> type = target.getClass();
4750
Class<?>[] interfaces = getAllInterfaces(type, signatureMap);
4851
if (interfaces.length > 0) {
49-
return Proxy.newProxyInstance(type.getClassLoader(), interfaces, new Plugin(target, interceptor, signatureMap));
50-
}
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));}
5164
return target;
5265
}
5366

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

79+
private static void mapping(Interceptor interceptor, Map<Class<?>, Set<Method>> signatureMap, Map<Method, List<Interceptor>> interceptorMap) {
80+
for (Set<Method> methods : signatureMap.values()) {
81+
for (Method method : methods) {
82+
interceptorMap.computeIfAbsent(method, (key) -> new ArrayList<>()).add(interceptor);
83+
}
84+
}
85+
}
86+
6787
private static Map<Class<?>, Set<Method>> getSignatureMap(Interceptor interceptor) {
6888
Intercepts interceptsAnnotation = interceptor.getClass().getAnnotation(Intercepts.class);
6989
// issue #251
@@ -74,7 +94,7 @@ private static Map<Class<?>, Set<Method>> getSignatureMap(Interceptor intercepto
7494
Signature[] sigs = interceptsAnnotation.value();
7595
Map<Class<?>, Set<Method>> signatureMap = new HashMap<>();
7696
for (Signature sig : sigs) {
77-
Set<Method> methods = MapUtil.computeIfAbsent(signatureMap, sig.type(), k -> new HashSet<>());
97+
Set<Method> methods = signatureMap.computeIfAbsent(sig.type(), k -> new HashSet<>());
7898
try {
7999
Method method = sig.type().getMethod(sig.method(), sig.args());
80100
methods.add(method);

0 commit comments

Comments
 (0)