|
29 | 29 | import org.springframework.core.BridgeMethodResolver;
|
30 | 30 | import org.springframework.core.GenericTypeResolver;
|
31 | 31 | import org.springframework.core.MethodParameter;
|
| 32 | +import org.springframework.core.ResolvableType; |
32 | 33 | import org.springframework.core.annotation.AnnotatedElementUtils;
|
33 | 34 | import org.springframework.core.annotation.SynthesizingMethodParameter;
|
34 | 35 | import org.springframework.http.HttpStatus;
|
@@ -81,6 +82,9 @@ public class HandlerMethod {
|
81 | 82 | @Nullable
|
82 | 83 | private HandlerMethod resolvedFromHandlerMethod;
|
83 | 84 |
|
| 85 | + @Nullable |
| 86 | + private volatile List<Annotation[][]> interfaceParameterAnnotations; |
| 87 | + |
84 | 88 |
|
85 | 89 | /**
|
86 | 90 | * Create an instance from a bean instance and a method.
|
@@ -323,8 +327,43 @@ public HandlerMethod createWithResolvedBean() {
|
323 | 327 | * @since 4.3
|
324 | 328 | */
|
325 | 329 | public String getShortLogMessage() {
|
326 |
| - int args = this.method.getParameterCount(); |
327 |
| - return getBeanType().getName() + "#" + this.method.getName() + "[" + args + " args]"; |
| 330 | + return getBeanType().getName() + "#" + this.method.getName() + |
| 331 | + "[" + this.method.getParameterCount() + " args]"; |
| 332 | + } |
| 333 | + |
| 334 | + |
| 335 | + private List<Annotation[][]> getInterfaceParameterAnnotations() { |
| 336 | + List<Annotation[][]> parameterAnnotations = this.interfaceParameterAnnotations; |
| 337 | + if (parameterAnnotations == null) { |
| 338 | + parameterAnnotations = new ArrayList<>(); |
| 339 | + for (Class<?> ifc : this.method.getDeclaringClass().getInterfaces()) { |
| 340 | + for (Method candidate : ifc.getMethods()) { |
| 341 | + if (isOverrideFor(candidate)) { |
| 342 | + parameterAnnotations.add(candidate.getParameterAnnotations()); |
| 343 | + } |
| 344 | + } |
| 345 | + } |
| 346 | + this.interfaceParameterAnnotations = parameterAnnotations; |
| 347 | + } |
| 348 | + return parameterAnnotations; |
| 349 | + } |
| 350 | + |
| 351 | + private boolean isOverrideFor(Method candidate) { |
| 352 | + if (!candidate.getName().equals(this.method.getName()) || |
| 353 | + candidate.getParameterCount() != this.method.getParameterCount()) { |
| 354 | + return false; |
| 355 | + } |
| 356 | + Class<?>[] paramTypes = this.method.getParameterTypes(); |
| 357 | + if (Arrays.equals(candidate.getParameterTypes(), paramTypes)) { |
| 358 | + return true; |
| 359 | + } |
| 360 | + for (int i = 0; i < paramTypes.length; i++) { |
| 361 | + if (paramTypes[i] != |
| 362 | + ResolvableType.forMethodParameter(candidate, i, this.method.getDeclaringClass()).resolve()) { |
| 363 | + return false; |
| 364 | + } |
| 365 | + } |
| 366 | + return true; |
328 | 367 | }
|
329 | 368 |
|
330 | 369 |
|
@@ -387,30 +426,24 @@ public Annotation[] getParameterAnnotations() {
|
387 | 426 | Annotation[] anns = this.combinedAnnotations;
|
388 | 427 | if (anns == null) {
|
389 | 428 | anns = super.getParameterAnnotations();
|
390 |
| - Class<?>[] ifcs = getDeclaringClass().getInterfaces(); |
391 |
| - for (Class<?> ifc : ifcs) { |
392 |
| - try { |
393 |
| - Method method = ifc.getMethod(getExecutable().getName(), getExecutable().getParameterTypes()); |
394 |
| - Annotation[] paramAnns = method.getParameterAnnotations()[getParameterIndex()]; |
395 |
| - if (paramAnns.length > 0) { |
396 |
| - List<Annotation> merged = new ArrayList<>(anns.length + paramAnns.length); |
397 |
| - merged.addAll(Arrays.asList(anns)); |
398 |
| - for (Annotation fieldAnn : paramAnns) { |
399 |
| - boolean existingType = false; |
400 |
| - for (Annotation ann : anns) { |
401 |
| - if (ann.annotationType() == fieldAnn.annotationType()) { |
402 |
| - existingType = true; |
403 |
| - break; |
404 |
| - } |
405 |
| - } |
406 |
| - if (!existingType) { |
407 |
| - merged.add(fieldAnn); |
| 429 | + for (Annotation[][] ifcAnns : getInterfaceParameterAnnotations()) { |
| 430 | + Annotation[] paramAnns = ifcAnns[getParameterIndex()]; |
| 431 | + if (paramAnns.length > 0) { |
| 432 | + List<Annotation> merged = new ArrayList<>(anns.length + paramAnns.length); |
| 433 | + merged.addAll(Arrays.asList(anns)); |
| 434 | + for (Annotation paramAnn : paramAnns) { |
| 435 | + boolean existingType = false; |
| 436 | + for (Annotation ann : anns) { |
| 437 | + if (ann.annotationType() == paramAnn.annotationType()) { |
| 438 | + existingType = true; |
| 439 | + break; |
408 | 440 | }
|
409 | 441 | }
|
410 |
| - anns = merged.toArray(new Annotation[0]); |
| 442 | + if (!existingType) { |
| 443 | + merged.add(paramAnn); |
| 444 | + } |
411 | 445 | }
|
412 |
| - } |
413 |
| - catch (NoSuchMethodException ex) { |
| 446 | + anns = merged.toArray(new Annotation[0]); |
414 | 447 | }
|
415 | 448 | }
|
416 | 449 | this.combinedAnnotations = anns;
|
|
0 commit comments