diff --git a/spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java b/spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java index 83358da1594b..01734d3bab83 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java @@ -193,6 +193,12 @@ public static boolean isFinalizeMethod(@Nullable Method method) { */ public static Method getMostSpecificMethod(Method method, @Nullable Class targetClass) { Class specificTargetClass = (targetClass != null ? ClassUtils.getUserClass(targetClass) : null); + Class[] interfaces = targetClass.getInterfaces(); + for (Class itf : interfaces) { + Method mostSpecificMethod = getMostSpecificMethod(method, itf); + if (!method.equals(mostSpecificMethod)) + return mostSpecificMethod; + } Method resolvedMethod = ClassUtils.getMostSpecificMethod(method, specificTargetClass); // If we are dealing with method with generic parameters, find the original method. return BridgeMethodResolver.findBridgedMethod(resolvedMethod); diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java index c8982c81a74e..bfcee21d6efa 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java @@ -556,7 +556,7 @@ public static A findAnnotation(Method method, @Nullable C } @Nullable - private static A searchOnInterfaces(Method method, Class annotationType, Class... ifcs) { + public static A searchOnInterfaces(Method method, Class annotationType, Class... ifcs) { for (Class ifc : ifcs) { Set annotatedMethods = getAnnotatedMethodsInBaseType(ifc); if (!annotatedMethods.isEmpty()) { diff --git a/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java b/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java index 0ae0c1f5eec1..842f23a3c3ce 100644 --- a/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java +++ b/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java @@ -336,6 +336,13 @@ private List getInterfaceParameterAnnotations() { List parameterAnnotations = this.interfaceParameterAnnotations; if (parameterAnnotations == null) { parameterAnnotations = new ArrayList<>(); + for (Class ifc : this.beanType.getInterfaces()) { + for (Method candidate : ifc.getMethods()) { + if (isOverrideFor(candidate)) { + parameterAnnotations.add(candidate.getParameterAnnotations()); + } + } + } for (Class ifc : this.method.getDeclaringClass().getInterfaces()) { for (Method candidate : ifc.getMethods()) { if (isOverrideFor(candidate)) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java index 6289027d4dec..4b4877e2fa99 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java @@ -218,6 +218,9 @@ protected boolean isHandler(Class beanType) { @Nullable protected RequestMappingInfo getMappingForMethod(Method method, Class handlerType) { RequestMappingInfo info = createRequestMappingInfo(method); + if (info == null) { + info = createRequestMappingInfo(method, handlerType.getInterfaces()); + } if (info != null) { RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType); if (typeInfo != null) {