|
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 | 27 |
|
|
31 | 33 | public class Plugin implements InvocationHandler {
|
32 | 34 |
|
33 | 35 | 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; |
36 | 37 |
|
37 |
| - private Plugin(Object target, Interceptor interceptor, Map<Class<?>, Set<Method>> signatureMap) { |
| 38 | + private Plugin(Object target, Map<Method, List<Interceptor>> interceptorMap) { |
38 | 39 | 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; |
41 | 45 | }
|
42 | 46 |
|
43 | 47 | public static Object wrap(Object target, Interceptor interceptor) {
|
44 | 48 | Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor);
|
45 | 49 | Class<?> type = target.getClass();
|
46 | 50 | Class<?>[] interfaces = getAllInterfaces(type, signatureMap);
|
47 | 51 | 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)); |
52 | 64 | }
|
53 | 65 | return target;
|
54 | 66 | }
|
55 | 67 |
|
56 | 68 | @Override
|
57 | 69 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
58 | 70 | 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(); |
62 | 74 | }
|
63 | 75 | return method.invoke(target, args);
|
64 | 76 | } catch (Exception e) {
|
65 | 77 | throw ExceptionUtil.unwrapThrowable(e);
|
66 | 78 | }
|
67 | 79 | }
|
68 | 80 |
|
| 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 | + |
69 | 89 | private static Map<Class<?>, Set<Method>> getSignatureMap(Interceptor interceptor) {
|
70 | 90 | Intercepts interceptsAnnotation = interceptor.getClass().getAnnotation(Intercepts.class);
|
71 | 91 | // issue #251
|
|
0 commit comments