From 5f5e5e9e867ef51b8777b5f6df25bf3658c62c32 Mon Sep 17 00:00:00 2001 From: s-mop <516671327@qq.com> Date: Thu, 6 Sep 2018 11:17:01 +0800 Subject: [PATCH 1/9] support for methods that declared in interfaces and implemented in super class --- .../core/annotation/AnnotationUtils.java | 2 +- .../annotation/RequestMappingHandlerMapping.java | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) 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-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..e1dbdacfe4bd 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 @@ -28,6 +28,7 @@ import org.springframework.context.EmbeddedValueResolverAware; import org.springframework.core.annotation.AnnotatedElementUtils; +import org.springframework.core.annotation.AnnotationUtils; import org.springframework.lang.Nullable; import org.springframework.stereotype.Controller; import org.springframework.util.Assert; @@ -218,6 +219,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) { @@ -259,6 +263,17 @@ private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) { getCustomTypeCondition((Class) element) : getCustomMethodCondition((Method) element)); return (requestMapping != null ? createRequestMappingInfo(requestMapping, condition) : null); } + + /** + * support for methods that declared in interfaces and implemented in super class + * @since 5.1 + */ + @Nullable + private RequestMappingInfo createRequestMappingInfo(Method method, Class[] ifcs) { + RequestMapping requestMapping = AnnotationUtils.searchOnInterfaces(method, RequestMapping.class, ifcs); + RequestCondition condition = getCustomMethodCondition(method); + return (requestMapping != null ? createRequestMappingInfo(requestMapping, condition) : null); + } /** * Provide a custom type-level request condition. From 3dc7fc0c85b8f3caa42717208d2b9aa1303bf006 Mon Sep 17 00:00:00 2001 From: s-mop <516671327@qq.com> Date: Thu, 6 Sep 2018 11:25:48 +0800 Subject: [PATCH 2/9] fix code style --- .../mvc/method/annotation/RequestMappingHandlerMapping.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 e1dbdacfe4bd..faffcf02bf31 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 @@ -263,9 +263,9 @@ private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) { getCustomTypeCondition((Class) element) : getCustomMethodCondition((Method) element)); return (requestMapping != null ? createRequestMappingInfo(requestMapping, condition) : null); } - + /** - * support for methods that declared in interfaces and implemented in super class + * Support for methods that declared in interfaces and implemented in super class. * @since 5.1 */ @Nullable From c76f017172938a9883e14b6804550ec0ca35f035 Mon Sep 17 00:00:00 2001 From: smop <516671327@qq.com> Date: Thu, 15 Nov 2018 16:13:03 +0800 Subject: [PATCH 3/9] AOP support for PR #1950 --- .../main/java/org/springframework/aop/support/AopUtils.java | 6 ++++++ 1 file changed, 6 insertions(+) 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..e4f26cd96a6e 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 (mostSpecificMethod != method) + 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); From 5f03ae716c1ac4973e0e48f7a9c1fccaf07563ef Mon Sep 17 00:00:00 2001 From: smop <516671327@qq.com> Date: Thu, 15 Nov 2018 16:47:03 +0800 Subject: [PATCH 4/9] fix for code bad smell --- .../src/main/java/org/springframework/aop/support/AopUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 e4f26cd96a6e..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 @@ -196,7 +196,7 @@ public static Method getMostSpecificMethod(Method method, @Nullable Class tar Class[] interfaces = targetClass.getInterfaces(); for (Class itf : interfaces) { Method mostSpecificMethod = getMostSpecificMethod(method, itf); - if (mostSpecificMethod != method) + if (!method.equals(mostSpecificMethod)) return mostSpecificMethod; } Method resolvedMethod = ClassUtils.getMostSpecificMethod(method, specificTargetClass); From d4b13333cd040d769894b98952e5dfba0f65afd4 Mon Sep 17 00:00:00 2001 From: smop <516671327@qq.com> Date: Thu, 20 Dec 2018 16:40:28 +0800 Subject: [PATCH 5/9] try getInterfaceParameterAnnotations from interfaces which implemented in 'this.beanType' --- .../java/org/springframework/web/method/HandlerMethod.java | 7 +++++++ 1 file changed, 7 insertions(+) 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)) { From 071d6ea7941c65e572431c20c9ad50f17de2e6b9 Mon Sep 17 00:00:00 2001 From: smop <516671327@qq.com> Date: Fri, 21 Dec 2018 15:31:28 +0800 Subject: [PATCH 6/9] logic optimized --- .../springframework/core/annotation/AnnotationUtils.java | 2 +- .../method/annotation/RequestMappingHandlerMapping.java | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) 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 bfcee21d6efa..c8982c81a74e 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 - public static A searchOnInterfaces(Method method, Class annotationType, Class... ifcs) { + private static A searchOnInterfaces(Method method, Class annotationType, Class... ifcs) { for (Class ifc : ifcs) { Set annotatedMethods = getAnnotatedMethodsInBaseType(ifc); if (!annotatedMethods.isEmpty()) { 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 faffcf02bf31..906289d3a689 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 @@ -26,8 +26,10 @@ import java.util.function.Predicate; import javax.servlet.http.HttpServletRequest; +import org.springframework.aop.support.AopUtils; import org.springframework.context.EmbeddedValueResolverAware; import org.springframework.core.annotation.AnnotatedElementUtils; +import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.lang.Nullable; import org.springframework.stereotype.Controller; @@ -218,10 +220,8 @@ protected boolean isHandler(Class beanType) { @Override @Nullable protected RequestMappingInfo getMappingForMethod(Method method, Class handlerType) { - RequestMappingInfo info = createRequestMappingInfo(method); - if (info == null) { - info = createRequestMappingInfo(method, handlerType.getInterfaces()); - } + Method mostSpecificMethod = AopUtils.getMostSpecificMethod(method, handlerType); + RequestMappingInfo info = createRequestMappingInfo(mostSpecificMethod); if (info != null) { RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType); if (typeInfo != null) { From ac3da6f94fc1b1d9efe2c67c1214798d82c4938d Mon Sep 17 00:00:00 2001 From: smop <516671327@qq.com> Date: Fri, 21 Dec 2018 15:31:51 +0800 Subject: [PATCH 7/9] remove unused --- .../annotation/RequestMappingHandlerMapping.java | 11 ----------- 1 file changed, 11 deletions(-) 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 906289d3a689..47e594503266 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 @@ -264,17 +264,6 @@ private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) { return (requestMapping != null ? createRequestMappingInfo(requestMapping, condition) : null); } - /** - * Support for methods that declared in interfaces and implemented in super class. - * @since 5.1 - */ - @Nullable - private RequestMappingInfo createRequestMappingInfo(Method method, Class[] ifcs) { - RequestMapping requestMapping = AnnotationUtils.searchOnInterfaces(method, RequestMapping.class, ifcs); - RequestCondition condition = getCustomMethodCondition(method); - return (requestMapping != null ? createRequestMappingInfo(requestMapping, condition) : null); - } - /** * Provide a custom type-level request condition. * The custom {@link RequestCondition} can be of any type so long as the From 3cc488ab85dd9eb488035d706993709b071b4847 Mon Sep 17 00:00:00 2001 From: smop <516671327@qq.com> Date: Thu, 27 Dec 2018 10:12:51 +0800 Subject: [PATCH 8/9] remove unused imports --- .../mvc/method/annotation/RequestMappingHandlerMapping.java | 2 -- 1 file changed, 2 deletions(-) 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 47e594503266..fbe2e84a0220 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 @@ -29,8 +29,6 @@ import org.springframework.aop.support.AopUtils; import org.springframework.context.EmbeddedValueResolverAware; import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.core.annotation.AnnotationAttributes; -import org.springframework.core.annotation.AnnotationUtils; import org.springframework.lang.Nullable; import org.springframework.stereotype.Controller; import org.springframework.util.Assert; From e287e14a798650fdaac2d3a7ddaebd275205a0ea Mon Sep 17 00:00:00 2001 From: smop <516671327@qq.com> Date: Thu, 27 Dec 2018 15:55:40 +0800 Subject: [PATCH 9/9] revert useless --- .../springframework/core/annotation/AnnotationUtils.java | 2 +- .../method/annotation/RequestMappingHandlerMapping.java | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) 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-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 fbe2e84a0220..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 @@ -26,7 +26,6 @@ import java.util.function.Predicate; import javax.servlet.http.HttpServletRequest; -import org.springframework.aop.support.AopUtils; import org.springframework.context.EmbeddedValueResolverAware; import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.lang.Nullable; @@ -218,8 +217,10 @@ protected boolean isHandler(Class beanType) { @Override @Nullable protected RequestMappingInfo getMappingForMethod(Method method, Class handlerType) { - Method mostSpecificMethod = AopUtils.getMostSpecificMethod(method, handlerType); - RequestMappingInfo info = createRequestMappingInfo(mostSpecificMethod); + RequestMappingInfo info = createRequestMappingInfo(method); + if (info == null) { + info = createRequestMappingInfo(method, handlerType.getInterfaces()); + } if (info != null) { RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType); if (typeInfo != null) {