18
18
import java .lang .reflect .InvocationHandler ;
19
19
import java .lang .reflect .Method ;
20
20
import java .lang .reflect .Proxy ;
21
+ import java .util .ArrayList ;
21
22
import java .util .HashMap ;
22
23
import java .util .HashSet ;
24
+ import java .util .List ;
23
25
import java .util .Map ;
24
26
import java .util .Set ;
25
-
26
27
import org .apache .ibatis .reflection .ExceptionUtil ;
27
- import org . apache . ibatis . util . MapUtil ;
28
+
28
29
29
30
/**
30
31
* @author Clinton Begin
31
32
*/
32
33
public class Plugin implements InvocationHandler {
33
34
34
35
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 ;
37
37
38
- private Plugin (Object target , Interceptor interceptor , Map <Class <?>, Set < Method >> signatureMap ) {
38
+ private Plugin (Object target , Map <Method , List < Interceptor >> interceptorMap ) {
39
39
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 ;
42
45
}
43
46
44
47
public static Object wrap (Object target , Interceptor interceptor ) {
45
48
Map <Class <?>, Set <Method >> signatureMap = getSignatureMap (interceptor );
46
49
Class <?> type = target .getClass ();
47
50
Class <?>[] interfaces = getAllInterfaces (type , signatureMap );
48
51
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 ));}
51
64
return target ;
52
65
}
53
66
54
67
@ Override
55
68
public Object invoke (Object proxy , Method method , Object [] args ) throws Throwable {
56
69
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 ();}
61
73
return method .invoke (target , args );
62
74
} catch (Exception e ) {
63
75
throw ExceptionUtil .unwrapThrowable (e );
64
76
}
65
77
}
66
78
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
+
67
87
private static Map <Class <?>, Set <Method >> getSignatureMap (Interceptor interceptor ) {
68
88
Intercepts interceptsAnnotation = interceptor .getClass ().getAnnotation (Intercepts .class );
69
89
// issue #251
@@ -74,7 +94,7 @@ private static Map<Class<?>, Set<Method>> getSignatureMap(Interceptor intercepto
74
94
Signature [] sigs = interceptsAnnotation .value ();
75
95
Map <Class <?>, Set <Method >> signatureMap = new HashMap <>();
76
96
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 <>());
78
98
try {
79
99
Method method = sig .type ().getMethod (sig .method (), sig .args ());
80
100
methods .add (method );
0 commit comments