|
1 | 1 | /*
|
2 |
| - * Copyright 2002-2020 the original author or authors. |
| 2 | + * Copyright 2002-2023 the original author or authors. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
|
27 | 27 | import org.apache.commons.logging.LogFactory;
|
28 | 28 |
|
29 | 29 | import org.springframework.aop.AfterAdvice;
|
| 30 | +import org.springframework.aop.framework.AopConfigException; |
30 | 31 | import org.springframework.lang.Nullable;
|
31 | 32 | import org.springframework.util.Assert;
|
32 | 33 |
|
@@ -78,21 +79,44 @@ public ThrowsAdviceInterceptor(Object throwsAdvice) {
|
78 | 79 |
|
79 | 80 | Method[] methods = throwsAdvice.getClass().getMethods();
|
80 | 81 | for (Method method : methods) {
|
81 |
| - if (method.getName().equals(AFTER_THROWING) && |
82 |
| - (method.getParameterCount() == 1 || method.getParameterCount() == 4)) { |
83 |
| - Class<?> throwableParam = method.getParameterTypes()[method.getParameterCount() - 1]; |
84 |
| - if (Throwable.class.isAssignableFrom(throwableParam)) { |
85 |
| - // An exception handler to register... |
86 |
| - this.exceptionHandlerMap.put(throwableParam, method); |
87 |
| - if (logger.isDebugEnabled()) { |
88 |
| - logger.debug("Found exception handler method on throws advice: " + method); |
| 82 | + if (method.getName().equals(AFTER_THROWING)) { |
| 83 | + Class<?> throwableParam = null; |
| 84 | + if (method.getParameterCount() == 1) { |
| 85 | + // just a Throwable parameter |
| 86 | + throwableParam = method.getParameterTypes()[0]; |
| 87 | + if (!Throwable.class.isAssignableFrom(throwableParam)) { |
| 88 | + throw new AopConfigException("Invalid afterThrowing signature: " + |
| 89 | + "single argument must be a Throwable subclass"); |
89 | 90 | }
|
90 | 91 | }
|
| 92 | + else if (method.getParameterCount() == 4) { |
| 93 | + // Method, Object[], target, throwable |
| 94 | + Class<?>[] paramTypes = method.getParameterTypes(); |
| 95 | + if (!Method.class.equals(paramTypes[0]) || !Object[].class.equals(paramTypes[1]) || |
| 96 | + Throwable.class.equals(paramTypes[2]) || !Throwable.class.isAssignableFrom(paramTypes[3])) { |
| 97 | + throw new AopConfigException("Invalid afterThrowing signature: " + |
| 98 | + "four arguments must be Method, Object[], target, throwable: " + method); |
| 99 | + } |
| 100 | + throwableParam = paramTypes[3]; |
| 101 | + } |
| 102 | + if (throwableParam == null) { |
| 103 | + throw new AopConfigException("Unsupported afterThrowing signature: single throwable argument " + |
| 104 | + "or four arguments Method, Object[], target, throwable expected: " + method); |
| 105 | + } |
| 106 | + // An exception handler to register... |
| 107 | + Method existingMethod = this.exceptionHandlerMap.put(throwableParam, method); |
| 108 | + if (existingMethod != null) { |
| 109 | + throw new AopConfigException("Only one afterThrowing method per specific Throwable subclass " + |
| 110 | + "allowed: " + method + " / " + existingMethod); |
| 111 | + } |
| 112 | + if (logger.isDebugEnabled()) { |
| 113 | + logger.debug("Found exception handler method on throws advice: " + method); |
| 114 | + } |
91 | 115 | }
|
92 | 116 | }
|
93 | 117 |
|
94 | 118 | if (this.exceptionHandlerMap.isEmpty()) {
|
95 |
| - throw new IllegalArgumentException( |
| 119 | + throw new AopConfigException( |
96 | 120 | "At least one handler method must be found in class [" + throwsAdvice.getClass() + "]");
|
97 | 121 | }
|
98 | 122 | }
|
|
0 commit comments