diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMapping.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMapping.java
index e58948a0486..ad9335ecc2f 100644
--- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMapping.java
+++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMapping.java
@@ -133,8 +133,7 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi
*/
@Override
protected boolean isHandler(Class> beanType) {
- return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
- AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
+ return AnnotatedElementUtils.hasAnnotation(beanType, Controller.class);
}
/**
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 bfb424d433f..e896bd25a1d 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
@@ -266,8 +266,7 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi
*/
@Override
protected boolean isHandler(Class> beanType) {
- return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
- AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
+ return AnnotatedElementUtils.hasAnnotation(beanType, Controller.class);
}
/**
diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HandlerMethodAnnotationDetectionTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HandlerMethodAnnotationDetectionTests.java
index e0b9c866a78..9854477d73b 100644
--- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HandlerMethodAnnotationDetectionTests.java
+++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HandlerMethodAnnotationDetectionTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -78,7 +78,7 @@ class HandlerMethodAnnotationDetectionTests {
// { ParameterizedSubclassDoesNotOverrideConcreteImplementationsFromGenericAbstractSuperclass.class, true }, // CGLIB proxy
// { ParameterizedSubclassDoesNotOverrideConcreteImplementationsFromGenericAbstractSuperclass.class, false },
- { InterfaceController.class, true }, // JDK dynamic proxy
+ // { InterfaceController.class, true }, // JDK dynamic proxy (gh-22154: no longer supported))
{ InterfaceController.class, false },
{ ParameterizedInterfaceController.class, false }, // no AOP
@@ -250,6 +250,7 @@ class HandlerMethodAnnotationDetectionTests {
*
JDK Dynamic proxy: All annotations must be on the interface.
*
Without AOP: Annotations can be on interface methods except parameter annotations.
*/
+ @Controller
static class InterfaceController implements MappingInterface {
@Override
@@ -443,6 +444,7 @@ class HandlerMethodAnnotationDetectionTests {
*
All annotations can be on interface except parameter annotations.
*
Cannot be used as JDK dynamic proxy since parameterized interface does not contain type information.
*/
+ @Controller
static class ParameterizedInterfaceController implements MappingGenericInterface {
@Override
diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilderTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilderTests.java
index bce9d4f1a6b..dc49c0a539a 100644
--- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilderTests.java
+++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilderTests.java
@@ -77,6 +77,7 @@ import static org.springframework.web.servlet.mvc.method.annotation.MvcUriCompon
* @author Rossen Stoyanchev
* @author Sam Brannen
*/
+@SuppressWarnings("unused")
public class MvcUriComponentsBuilderTests {
private final MockHttpServletRequest request = new MockHttpServletRequest();
@@ -455,7 +456,8 @@ public class MvcUriComponentsBuilderTests {
this.request.setServerPort(9999);
this.request.setContextPath("/base");
- assertThat(fromController(PersonsAddressesController.class).buildAndExpand("123").toString()).isEqualTo("https://example.org:9999/base/api/people/123/addresses");
+ assertThat(fromController(PersonsAddressesController.class).buildAndExpand("123").toString())
+ .isEqualTo("https://example.org:9999/base/api/people/123/addresses");
}
@Test
@@ -468,8 +470,12 @@ public class MvcUriComponentsBuilderTests {
this.request.setServerPort(9999);
this.request.setContextPath("/base");
- assertThat(fromMethodCall(on(PersonsAddressesController.class).getAddressesForCountry("DE"))
- .buildAndExpand("123").toString()).isEqualTo("https://example.org:9999/base/api/people/123/addresses/DE");
+ String url = fromMethodCall(on(PersonsAddressesController.class)
+ .getAddressesForCountry("DE"))
+ .buildAndExpand("123")
+ .toString();
+
+ assertThat(url).isEqualTo("https://example.org:9999/base/api/people/123/addresses/DE");
}
private void initWebApplicationContext(Class> configClass) {
@@ -500,6 +506,7 @@ public class MvcUriComponentsBuilderTests {
}
+ @Controller
@RequestMapping("/people/{id}/addresses")
static class PersonsAddressesController {
@@ -509,6 +516,7 @@ public class MvcUriComponentsBuilderTests {
}
}
+ @Controller
@RequestMapping({"people"})
static class PathWithoutLeadingSlashController {
diff --git a/src/docs/asciidoc/web/webflux.adoc b/src/docs/asciidoc/web/webflux.adoc
index ac10e816b80..3c65f735914 100644
--- a/src/docs/asciidoc/web/webflux.adoc
+++ b/src/docs/asciidoc/web/webflux.adoc
@@ -1348,6 +1348,29 @@ directly to the response body versus view resolution and rendering with an HTML
+[[webflux-ann-requestmapping-proxying]]
+==== AOP Proxies
+[.small]#<>#
+
+In some cases, you may need to decorate a controller with an AOP proxy at runtime.
+One example is if you choose to have `@Transactional` annotations directly on the
+controller. When this is the case, for controllers specifically, we recommend
+using class-based proxying. This is automatically the case with such annotations
+directly on the controller.
+
+If the controller implements an interface, and needs AOP proxying, you may need to
+explicitly configure class-based proxying. For example, with `@EnableTransactionManagement`
+you can change to `@EnableTransactionManagement(proxyTargetClass = true)`, and with
+`` you can change to ``.
+
+NOTE: Keep in mind that as of 6.0, with interface proxying, Spring MVC no longer detects
+controllers based solely on a type-level `@RequestMapping` annotation on the interface.
+Please, enable class based proxying, or otherwise the interface must also have an
+`@Controller` annotation.
+
+
+
+
[[webflux-ann-requestmapping]]
=== Request Mapping
[.small]#<>#
diff --git a/src/docs/asciidoc/web/webmvc.adoc b/src/docs/asciidoc/web/webmvc.adoc
index e0237b498d7..7dc7df941dc 100644
--- a/src/docs/asciidoc/web/webmvc.adoc
+++ b/src/docs/asciidoc/web/webmvc.adoc
@@ -1512,17 +1512,23 @@ directly to the response body versus view resolution and rendering with an HTML
[[mvc-ann-requestmapping-proxying]]
==== AOP Proxies
+[.small]#<>#
In some cases, you may need to decorate a controller with an AOP proxy at runtime.
One example is if you choose to have `@Transactional` annotations directly on the
controller. When this is the case, for controllers specifically, we recommend
-using class-based proxying. This is typically the default choice with controllers.
-However, if a controller must implement an interface that is not a Spring Context
-callback (such as `InitializingBean`, `*Aware`, and others), you may need to explicitly
-configure class-based proxying. For example, with `` you can
-change to ``, and with
-`@EnableTransactionManagement` you can change to
-`@EnableTransactionManagement(proxyTargetClass = true)`.
+using class-based proxying. This is automatically the case with such annotations
+directly on the controller.
+
+If the controller implements an interface, and needs AOP proxying, you may need to
+explicitly configure class-based proxying. For example, with `@EnableTransactionManagement`
+you can change to `@EnableTransactionManagement(proxyTargetClass = true)`, and with
+`` you can change to ``.
+
+NOTE: Keep in mind that as of 6.0, with interface proxying, Spring MVC no longer detects
+controllers based solely on a type-level `@RequestMapping` annotation on the interface.
+Please, enable class based proxying, or otherwise the interface must also have an
+`@Controller` annotation.