diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/ResolvableMethod.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/ResolvableMethod.java index 1070c488dc..0b572755bc 100644 --- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/ResolvableMethod.java +++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/ResolvableMethod.java @@ -30,6 +30,7 @@ import org.springframework.core.annotation.AnnotationUtils; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.ReflectionUtils; +import org.springframework.web.reactive.result.method.InvocableHandlerMethod; /** * Convenience class for use in tests to resolve a {@link Method} and/or any of @@ -47,7 +48,7 @@ import org.springframework.util.ReflectionUtils; * response handling, the return type may be used as a hint: * *
- * ResolvableMethod resolvableMethod = ResolvableMethod.on(TestController.class);
+ * ResolvableMethod resolvableMethod = ResolvableMethod.onClass(TestController.class);
 
  * ResolvableType type = ResolvableType.forClassWithGenerics(Mono.class, View.class);
  * Method method = resolvableMethod.returning(type).resolve();
@@ -65,7 +66,10 @@ import org.springframework.util.ReflectionUtils;
  */
 public class ResolvableMethod {
 
-	private final Class targetClass;
+	private final Class objectClass;
+
+	private final Object object;
+
 
 	private String methodName;
 
@@ -75,36 +79,67 @@ public class ResolvableMethod {
 
 	private final List> annotationTypes = new ArrayList<>(4);
 
+	private final List> predicates = new ArrayList<>(4);
 
-	private ResolvableMethod(Class targetClass) {
-		this.targetClass = targetClass;
+
+
+	private ResolvableMethod(Class objectClass) {
+		Assert.notNull(objectClass);
+		this.objectClass = objectClass;
+		this.object = null;
+	}
+
+	private ResolvableMethod(Object object) {
+		Assert.notNull(object);
+		this.object = object;
+		this.objectClass = object.getClass();
 	}
 
 
+	/**
+	 * Methods that match the given name (regardless of arguments).
+	 */
 	public ResolvableMethod name(String methodName) {
 		this.methodName = methodName;
 		return this;
 	}
 
+	/**
+	 * Methods that match the given argument types.
+	 */
 	public ResolvableMethod argumentTypes(Class... argumentTypes) {
 		this.argumentTypes = argumentTypes;
 		return this;
 	}
 
+	/**
+	 * Methods declared to return the given type.
+	 */
 	public ResolvableMethod returning(ResolvableType resolvableType) {
 		this.returnType = resolvableType;
 		return this;
 	}
 
+	/**
+	 * Methods with the given annotation.
+	 */
 	public ResolvableMethod annotated(Class annotationType) {
 		this.annotationTypes.add(annotationType);
 		return this;
 	}
 
+	/**
+	 * Methods matching the given predicate.
+	 */
+	public final ResolvableMethod matching(Predicate methodPredicate) {
+		this.predicates.add(methodPredicate);
+		return this;
+	}
+
 	// Resolve methods
 
 	public Method resolve() {
-		Set methods = MethodIntrospector.selectMethods(this.targetClass,
+		Set methods = MethodIntrospector.selectMethods(this.objectClass,
 				(ReflectionUtils.MethodFilter) method -> {
 					if (this.methodName != null && !this.methodName.equals(method.getName())) {
 						return false;
@@ -116,15 +151,19 @@ public class ResolvableMethod {
 							return false;
 						}
 					}
-					if (!ObjectUtils.isEmpty(this.argumentTypes)) {
+					else if (!ObjectUtils.isEmpty(this.argumentTypes)) {
 						if (!Arrays.equals(this.argumentTypes, method.getParameterTypes())) {
 							return false;
 						}
 					}
-					for (Class annotationType : this.annotationTypes) {
-						if (AnnotationUtils.findAnnotation(method, annotationType) == null) {
-							return false;
-						}
+					else if (this.annotationTypes.stream()
+							.filter(annotType -> AnnotationUtils.findAnnotation(method, annotType) == null)
+							.findFirst()
+							.isPresent()) {
+						return false;
+					}
+					else if (this.predicates.stream().filter(p -> !p.test(method)).findFirst().isPresent()) {
+						return false;
 					}
 					return true;
 				});
@@ -139,6 +178,11 @@ public class ResolvableMethod {
 		return this.returnType != null ? this.returnType.toString() : null;
 	}
 
+	public InvocableHandlerMethod resolveHandlerMethod() {
+		Assert.notNull(this.object);
+		return new InvocableHandlerMethod(this.object, resolve());
+	}
+
 	public MethodParameter resolveReturnType() {
 		Method method = resolve();
 		return new MethodParameter(method, -1);
@@ -177,18 +221,21 @@ public class ResolvableMethod {
 		return matches.get(0);
 	}
 
-
-
-
 	@Override
 	public String toString() {
-		return "Class=" + this.targetClass + ", name= " + this.methodName +
-				", returnType=" + this.returnType + ", annotations=" + this.annotationTypes;
+		return "Class=" + this.objectClass +
+				", name=" + (this.methodName != null ? this.methodName : "") +
+				", returnType=" + (this.returnType != null ? this.returnType : "") +
+				", annotations=" + this.annotationTypes;
 	}
 
 
-	public static ResolvableMethod on(Class clazz) {
+	public static ResolvableMethod onClass(Class clazz) {
 		return new ResolvableMethod(clazz);
 	}
 
+	public static ResolvableMethod on(Object object) {
+		return new ResolvableMethod(object);
+	}
+
 }
\ No newline at end of file
diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/SimpleResultHandlerTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/SimpleResultHandlerTests.java
index 7aba79ee55..646956d4ef 100644
--- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/SimpleResultHandlerTests.java
+++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/SimpleResultHandlerTests.java
@@ -72,7 +72,7 @@ public class SimpleResultHandlerTests {
 	}
 
 	private void testSupports(ResolvableType type, boolean result) {
-		MethodParameter param = ResolvableMethod.on(TestController.class).returning(type).resolveReturnType();
+		MethodParameter param = ResolvableMethod.onClass(TestController.class).returning(type).resolveReturnType();
 		HandlerResult handlerResult = new HandlerResult(new TestController(), null, param);
 		assertEquals(result, this.resultHandler.supports(handlerResult));
 	}
diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/InvocableHandlerMethodTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/InvocableHandlerMethodTests.java
index 4984f9e056..08a8269369 100644
--- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/InvocableHandlerMethodTests.java
+++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/InvocableHandlerMethodTests.java
@@ -15,7 +15,6 @@
  */
 package org.springframework.web.reactive.result.method;
 
-import java.lang.reflect.Method;
 import java.net.URI;
 import java.util.Collections;
 import java.util.Optional;
@@ -30,7 +29,6 @@ import org.springframework.http.server.reactive.MockServerHttpRequest;
 import org.springframework.http.server.reactive.MockServerHttpResponse;
 import org.springframework.ui.ExtendedModelMap;
 import org.springframework.ui.ModelMap;
-import org.springframework.web.method.HandlerMethod;
 import org.springframework.web.reactive.HandlerResult;
 import org.springframework.web.reactive.result.ResolvableMethod;
 import org.springframework.web.server.ServerWebExchange;
@@ -150,8 +148,8 @@ public class InvocableHandlerMethodTests {
 
 
 	private InvocableHandlerMethod handlerMethod(String name) throws Exception {
-		Method method = ResolvableMethod.on(TestController.class).name(name).resolve();
-		return new InvocableHandlerMethod(new HandlerMethod(new TestController(), method));
+		TestController controller = new TestController();
+		return ResolvableMethod.on(controller).name(name).resolveHandlerMethod();
 	}
 
 	private void addResolver(InvocableHandlerMethod handlerMethod, Mono resolvedValue) {
diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMappingTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMappingTests.java
index 3d1955007f..000a8432d3 100644
--- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMappingTests.java
+++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMappingTests.java
@@ -52,6 +52,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.method.HandlerMethod;
 import org.springframework.web.reactive.HandlerMapping;
 import org.springframework.web.reactive.HandlerResult;
+import org.springframework.web.reactive.result.ResolvableMethod;
 import org.springframework.web.reactive.result.method.RequestMappingInfo.BuilderConfiguration;
 import org.springframework.web.server.MethodNotAllowedException;
 import org.springframework.web.server.NotAcceptableStatusException;
@@ -69,44 +70,31 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
-
+import static org.springframework.web.bind.annotation.RequestMethod.GET;
+import static org.springframework.web.bind.annotation.RequestMethod.HEAD;
+import static org.springframework.web.bind.annotation.RequestMethod.OPTIONS;
+import static org.springframework.web.reactive.result.method.RequestMappingInfo.paths;
 
 /**
  * Unit tests for {@link RequestMappingInfoHandlerMapping}.
- *
  * @author Rossen Stoyanchev
  */
 public class RequestMappingInfoHandlerMappingTests {
 
 	private TestRequestMappingInfoHandlerMapping handlerMapping;
 
-	private HandlerMethod fooMethod;
-
-	private HandlerMethod fooParamMethod;
-
-	private HandlerMethod barMethod;
-
-	private HandlerMethod emptyMethod;
-
 
 	@Before
 	public void setUp() throws Exception {
-		TestController testController = new TestController();
-
-		this.fooMethod = new HandlerMethod(testController, "foo");
-		this.fooParamMethod = new HandlerMethod(testController, "fooParam");
-		this.barMethod = new HandlerMethod(testController, "bar");
-		this.emptyMethod = new HandlerMethod(testController, "empty");
-
 		this.handlerMapping = new TestRequestMappingInfoHandlerMapping();
-		this.handlerMapping.registerHandler(testController);
+		this.handlerMapping.registerHandler(new TestController());
 	}
 
 
 	@Test
 	public void getMappingPathPatterns() throws Exception {
 		String[] patterns = {"/foo/*", "/foo", "/bar/*", "/bar"};
-		RequestMappingInfo info = RequestMappingInfo.paths(patterns).build();
+		RequestMappingInfo info = paths(patterns).build();
 		Set actual = this.handlerMapping.getMappingPathPatterns(info);
 
 		assertEquals(new HashSet<>(Arrays.asList(patterns)), actual);
@@ -114,38 +102,53 @@ public class RequestMappingInfoHandlerMappingTests {
 
 	@Test
 	public void getHandlerDirectMatch() throws Exception {
+		String[] patterns = new String[] {"/foo"};
+		String[] params = new String[] {};
+		Method expected = resolveMethod(new TestController(), patterns, null, params);
+
 		ServerWebExchange exchange = createExchange(HttpMethod.GET, "/foo");
-		HandlerMethod handlerMethod = getHandler(exchange);
-		assertEquals(this.fooMethod.getMethod(), handlerMethod.getMethod());
+		HandlerMethod hm = (HandlerMethod) this.handlerMapping.getHandler(exchange).block();
+
+		assertEquals(expected, hm.getMethod());
 	}
 
 	@Test
 	public void getHandlerGlobMatch() throws Exception {
+		String[] patterns = new String[] {"/ba*"};
+		RequestMethod[] methods = new RequestMethod[] {GET, HEAD};
+		Method expected = resolveMethod(new TestController(), patterns, methods, null);
+
 		ServerWebExchange exchange = createExchange(HttpMethod.GET, "/bar");
-		HandlerMethod handlerMethod = getHandler(exchange);
-		assertEquals(this.barMethod.getMethod(), handlerMethod.getMethod());
+		HandlerMethod hm = (HandlerMethod) this.handlerMapping.getHandler(exchange).block();
+
+		assertEquals(expected, hm.getMethod());
 	}
 
 	@Test
 	public void getHandlerEmptyPathMatch() throws Exception {
-		ServerWebExchange exchange = createExchange(HttpMethod.GET, "");
-		HandlerMethod handlerMethod = getHandler(exchange);
+		String[] patterns = new String[] {""};
+		Method expected = resolveMethod(new TestController(), patterns, null, null);
 
-		assertEquals(this.emptyMethod.getMethod(), handlerMethod.getMethod());
+		ServerWebExchange exchange = createExchange(HttpMethod.GET, "");
+		HandlerMethod hm = (HandlerMethod) this.handlerMapping.getHandler(exchange).block();
+		assertEquals(expected, hm.getMethod());
 
 		exchange = createExchange(HttpMethod.GET, "/");
-		handlerMethod = getHandler(exchange);
-
-		assertEquals(this.emptyMethod.getMethod(), handlerMethod.getMethod());
+		hm = (HandlerMethod) this.handlerMapping.getHandler(exchange).block();
+		assertEquals(expected, hm.getMethod());
 	}
 
 	@Test
 	public void getHandlerBestMatch() throws Exception {
+		String[] patterns = new String[] {"/foo"};
+		String[] params = new String[] {"p"};
+		Method expected = resolveMethod(new TestController(), patterns, null, params);
+
 		ServerWebExchange exchange = createExchange(HttpMethod.GET, "/foo");
 		exchange.getRequest().getQueryParams().add("p", "anything");
-		HandlerMethod handlerMethod = getHandler(exchange);
+		HandlerMethod hm = (HandlerMethod) this.handlerMapping.getHandler(exchange).block();
 
-		assertEquals(this.fooParamMethod.getMethod(), handlerMethod.getMethod());
+		assertEquals(expected, hm.getMethod());
 	}
 
 	@Test
@@ -179,24 +182,21 @@ public class RequestMappingInfoHandlerMappingTests {
 		ServerWebExchange exchange = createExchange(HttpMethod.PUT, "/person/1");
 		exchange.getRequest().getHeaders().add("Content-Type", "bogus");
 		Mono mono = this.handlerMapping.getHandler(exchange);
+
 		assertError(mono, UnsupportedMediaTypeStatusException.class,
 				ex -> assertEquals("Request failure [status: 415, " +
 						"reason: \"Invalid mime type \"bogus\": does not contain '/'\"]",
 						ex.getMessage()));
 	}
 
-	// SPR-8462
-
-	@Test
+	@Test // SPR-8462
 	public void getHandlerTestMediaTypeNotAcceptable() throws Exception {
 		testMediaTypeNotAcceptable("/persons");
 		testMediaTypeNotAcceptable("/persons/");
 		testMediaTypeNotAcceptable("/persons.json");
 	}
 
-	// SPR-12854
-
-	@Test
+	@Test // SPR-12854
 	public void getHandlerTestRequestParamMismatch() throws Exception {
 		ServerWebExchange exchange = createExchange(HttpMethod.GET, "/params");
 		Mono mono = this.handlerMapping.getHandler(exchange);
@@ -218,23 +218,22 @@ public class RequestMappingInfoHandlerMappingTests {
 	public void getHandlerProducibleMediaTypesAttribute() throws Exception {
 		ServerWebExchange exchange = createExchange(HttpMethod.GET, "/content");
 		exchange.getRequest().getHeaders().setAccept(Collections.singletonList(MediaType.APPLICATION_XML));
-		getHandler(exchange);
+		this.handlerMapping.getHandler(exchange).block();
 
 		String name = HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE;
 		assertEquals(Collections.singleton(MediaType.APPLICATION_XML), exchange.getAttributes().get(name));
 
 		exchange = createExchange(HttpMethod.GET, "/content");
 		exchange.getRequest().getHeaders().setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
-		getHandler(exchange);
+		this.handlerMapping.getHandler(exchange).block();
 
 		assertNull("Negated expression shouldn't be listed as producible type",
 				exchange.getAttributes().get(name));
 	}
 
-	@SuppressWarnings("unchecked")
-	@Test
+	@Test @SuppressWarnings("unchecked")
 	public void handleMatchUriTemplateVariables() throws Exception {
-		RequestMappingInfo key = RequestMappingInfo.paths("/{path1}/{path2}").build();
+		RequestMappingInfo key = paths("/{path1}/{path2}").build();
 		ServerWebExchange exchange = createExchange(HttpMethod.GET, "/1/2");
 		String lookupPath = exchange.getRequest().getURI().getPath();
 		this.handlerMapping.handleMatch(key, lookupPath, exchange);
@@ -247,11 +246,9 @@ public class RequestMappingInfoHandlerMappingTests {
 		assertEquals("2", uriVariables.get("path2"));
 	}
 
-	// SPR-9098
-
-	@Test
+	@Test // SPR-9098
 	public void handleMatchUriTemplateVariablesDecode() throws Exception {
-		RequestMappingInfo key = RequestMappingInfo.paths("/{group}/{identifier}").build();
+		RequestMappingInfo key = paths("/{group}/{identifier}").build();
 		ServerWebExchange exchange = createExchange(HttpMethod.GET, "/group/a%2Fb");
 
 		HttpRequestPathHelper pathHelper = new HttpRequestPathHelper();
@@ -272,7 +269,7 @@ public class RequestMappingInfoHandlerMappingTests {
 
 	@Test
 	public void handleMatchBestMatchingPatternAttribute() throws Exception {
-		RequestMappingInfo key = RequestMappingInfo.paths("/{path1}/2", "/**").build();
+		RequestMappingInfo key = paths("/{path1}/2", "/**").build();
 		ServerWebExchange exchange = createExchange(HttpMethod.GET, "/1/2");
 		this.handlerMapping.handleMatch(key, "/1/2", exchange);
 
@@ -281,7 +278,7 @@ public class RequestMappingInfoHandlerMappingTests {
 
 	@Test
 	public void handleMatchBestMatchingPatternAttributeNoPatternsDefined() throws Exception {
-		RequestMappingInfo key = RequestMappingInfo.paths().build();
+		RequestMappingInfo key = paths().build();
 		ServerWebExchange exchange = createExchange(HttpMethod.GET, "/1/2");
 
 		this.handlerMapping.handleMatch(key, "/1/2", exchange);
@@ -333,8 +330,7 @@ public class RequestMappingInfoHandlerMappingTests {
 	public void handleMatchMatrixVariablesDecoding() throws Exception {
 		HttpRequestPathHelper urlPathHelper = new HttpRequestPathHelper();
 		urlPathHelper.setUrlDecode(false);
-
-		this.handlerMapping.setPathHelper(urlPathHelper );
+		this.handlerMapping.setPathHelper(urlPathHelper);
 
 		ServerWebExchange exchange = createExchange(HttpMethod.GET, "/");
 		handleMatch(exchange, "/path{filter}", "/path;mvar=a%2fb");
@@ -365,11 +361,6 @@ public class RequestMappingInfoHandlerMappingTests {
 				});
 	}
 
-	@SuppressWarnings("ConstantConditions")
-	private HandlerMethod getHandler(ServerWebExchange exchange) throws Exception {
-		Mono handler = this.handlerMapping.getHandler(exchange);
-		return (HandlerMethod) handler.block();
-	}
 
 	private void testHttpMediaTypeNotSupportedException(String url) throws Exception {
 		ServerWebExchange exchange = createExchange(HttpMethod.PUT, url);
@@ -384,7 +375,7 @@ public class RequestMappingInfoHandlerMappingTests {
 
 	private void testHttpOptions(String requestURI, String allowHeader) throws Exception {
 		ServerWebExchange exchange = createExchange(HttpMethod.OPTIONS, requestURI);
-		HandlerMethod handlerMethod = getHandler(exchange);
+		HandlerMethod handlerMethod = (HandlerMethod) this.handlerMapping.getHandler(exchange).block();
 
 		ModelMap model = new ExtendedModelMap();
 		Mono mono = new InvocableHandlerMethod(handlerMethod).invokeForRequest(exchange, model);
@@ -410,7 +401,7 @@ public class RequestMappingInfoHandlerMappingTests {
 	}
 
 	private void handleMatch(ServerWebExchange exchange, String pattern, String lookupPath) {
-		RequestMappingInfo info = RequestMappingInfo.paths(pattern).build();
+		RequestMappingInfo info = paths(pattern).build();
 		this.handlerMapping.handleMatch(info, lookupPath, exchange);
 	}
 
@@ -426,6 +417,29 @@ public class RequestMappingInfoHandlerMappingTests {
 		return (Map) exchange.getAttributes().get(attrName);
 	}
 
+	private Method resolveMethod(Object controller, String[] patterns,
+			RequestMethod[] methods, String[] params) {
+
+		return ResolvableMethod.on(controller)
+				.matching(method -> {
+					RequestMapping annot = AnnotatedElementUtils.findMergedAnnotation(method, RequestMapping.class);
+					if (annot == null) {
+						return false;
+					}
+					else if (patterns != null && !Arrays.equals(annot.path(), patterns)) {
+						return false;
+					}
+					else if (methods != null && !Arrays.equals(annot.method(), methods)) {
+						return false;
+					}
+					else if (params != null && (!Arrays.equals(annot.params(), params))) {
+						return false;
+					}
+					return true;
+				})
+				.resolve();
+	}
+
 
 	@SuppressWarnings("unused")
 	@Controller
@@ -439,11 +453,11 @@ public class RequestMappingInfoHandlerMappingTests {
 		public void fooParam() {
 		}
 
-		@RequestMapping(path = "/ba*", method = { RequestMethod.GET, RequestMethod.HEAD })
+		@RequestMapping(path = "/ba*", method = { GET, HEAD })
 		public void bar() {
 		}
 
-		@RequestMapping(value = "")
+		@RequestMapping(path = "")
 		public void empty() {
 		}
 
@@ -451,32 +465,32 @@ public class RequestMappingInfoHandlerMappingTests {
 		public void consumes(@RequestBody String text) {
 		}
 
-		@RequestMapping(value = "/persons", produces="application/xml")
+		@RequestMapping(path = "/persons", produces="application/xml")
 		public String produces() {
 			return "";
 		}
 
-		@RequestMapping(value = "/params", params="foo=bar")
+		@RequestMapping(path = "/params", params="foo=bar")
 		public String param() {
 			return "";
 		}
 
-		@RequestMapping(value = "/params", params="bar=baz")
+		@RequestMapping(path = "/params", params="bar=baz")
 		public String param2() {
 			return "";
 		}
 
-		@RequestMapping(value = "/content", produces="application/xml")
+		@RequestMapping(path = "/content", produces="application/xml")
 		public String xmlContent() {
 			return "";
 		}
 
-		@RequestMapping(value = "/content", produces="!application/xml")
+		@RequestMapping(path = "/content", produces="!application/xml")
 		public String nonXmlContent() {
 			return "";
 		}
 
-		@RequestMapping(value = "/something", method = RequestMethod.OPTIONS)
+		@RequestMapping(path = "/something", method = OPTIONS)
 		public HttpHeaders fooOptions() {
 			HttpHeaders headers = new HttpHeaders();
 			headers.add("Allow", "PUT,POST");
@@ -499,7 +513,7 @@ public class RequestMappingInfoHandlerMappingTests {
 
 	private static class TestRequestMappingInfoHandlerMapping extends RequestMappingInfoHandlerMapping {
 
-		public void registerHandler(Object handler) {
+		void registerHandler(Object handler) {
 			super.detectHandlerMethods(handler);
 		}
 
@@ -517,7 +531,7 @@ public class RequestMappingInfoHandlerMappingTests {
 				options.setPathMatcher(getPathMatcher());
 				options.setSuffixPatternMatch(true);
 				options.setTrailingSlashMatch(true);
-				return RequestMappingInfo.paths(annot.value()).methods(annot.method())
+				return paths(annot.value()).methods(annot.method())
 						.params(annot.params()).headers(annot.headers())
 						.consumes(annot.consumes()).produces(annot.produces())
 						.options(options).build();
diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/HttpEntityArgumentResolverTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/HttpEntityArgumentResolverTests.java
index 0df938c38b..86085d67e4 100644
--- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/HttpEntityArgumentResolverTests.java
+++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/HttpEntityArgumentResolverTests.java
@@ -73,13 +73,13 @@ import static org.springframework.core.ResolvableType.forClassWithGenerics;
  */
 public class HttpEntityArgumentResolverTests {
 
-	private HttpEntityArgumentResolver resolver = resolver();
+	private HttpEntityArgumentResolver resolver = createResolver();
 
 	private ServerWebExchange exchange;
 
 	private MockServerHttpRequest request;
 
-	private ResolvableMethod testMethod = ResolvableMethod.on(getClass()).name("handle");
+	private ResolvableMethod testMethod = ResolvableMethod.onClass(getClass()).name("handle");
 
 
 	@Before
@@ -89,15 +89,26 @@ public class HttpEntityArgumentResolverTests {
 		this.exchange = new DefaultServerWebExchange(this.request, response, new MockWebSessionManager());
 	}
 
+	private HttpEntityArgumentResolver createResolver() {
+		List> converters = new ArrayList<>();
+		converters.add(new CodecHttpMessageConverter<>(new StringDecoder()));
+
+		FormattingConversionService service = new DefaultFormattingConversionService();
+		service.addConverter(new MonoToCompletableFutureConverter());
+		service.addConverter(new ReactorToRxJava1Converter());
+
+		return new HttpEntityArgumentResolver(converters, service);
+	}
+
 
 	@Test
 	public void supports() throws Exception {
-		testSupports(httpEntity(String.class));
-		testSupports(httpEntity(forClassWithGenerics(Mono.class, String.class)));
-		testSupports(httpEntity(forClassWithGenerics(Single.class, String.class)));
-		testSupports(httpEntity(forClassWithGenerics(CompletableFuture.class, String.class)));
-		testSupports(httpEntity(forClassWithGenerics(Flux.class, String.class)));
-		testSupports(httpEntity(forClassWithGenerics(Observable.class, String.class)));
+		testSupports(httpEntityType(String.class));
+		testSupports(httpEntityType(forClassWithGenerics(Mono.class, String.class)));
+		testSupports(httpEntityType(forClassWithGenerics(Single.class, String.class)));
+		testSupports(httpEntityType(forClassWithGenerics(CompletableFuture.class, String.class)));
+		testSupports(httpEntityType(forClassWithGenerics(Flux.class, String.class)));
+		testSupports(httpEntityType(forClassWithGenerics(Observable.class, String.class)));
 		testSupports(forClassWithGenerics(RequestEntity.class, String.class));
 	}
 
@@ -112,7 +123,7 @@ public class HttpEntityArgumentResolverTests {
 
 	@Test
 	public void emptyBodyWithString() throws Exception {
-		ResolvableType type = httpEntity(String.class);
+		ResolvableType type = httpEntityType(String.class);
 		HttpEntity entity = resolveValueWithEmptyBody(type);
 
 		assertNull(entity.getBody());
@@ -120,7 +131,7 @@ public class HttpEntityArgumentResolverTests {
 
 	@Test
 	public void emptyBodyWithMono() throws Exception {
-		ResolvableType type = httpEntity(forClassWithGenerics(Mono.class, String.class));
+		ResolvableType type = httpEntityType(forClassWithGenerics(Mono.class, String.class));
 		HttpEntity> entity = resolveValueWithEmptyBody(type);
 
 		TestSubscriber.subscribe(entity.getBody())
@@ -131,7 +142,7 @@ public class HttpEntityArgumentResolverTests {
 
 	@Test
 	public void emptyBodyWithFlux() throws Exception {
-		ResolvableType type = httpEntity(forClassWithGenerics(Flux.class, String.class));
+		ResolvableType type = httpEntityType(forClassWithGenerics(Flux.class, String.class));
 		HttpEntity> entity = resolveValueWithEmptyBody(type);
 
 		TestSubscriber.subscribe(entity.getBody())
@@ -142,7 +153,7 @@ public class HttpEntityArgumentResolverTests {
 
 	@Test
 	public void emptyBodyWithSingle() throws Exception {
-		ResolvableType type = httpEntity(forClassWithGenerics(Single.class, String.class));
+		ResolvableType type = httpEntityType(forClassWithGenerics(Single.class, String.class));
 		HttpEntity> entity = resolveValueWithEmptyBody(type);
 
 		TestSubscriber.subscribe(RxJava1SingleConverter.from(entity.getBody()))
@@ -152,7 +163,7 @@ public class HttpEntityArgumentResolverTests {
 
 	@Test
 	public void emptyBodyWithObservable() throws Exception {
-		ResolvableType type = httpEntity(forClassWithGenerics(Observable.class, String.class));
+		ResolvableType type = httpEntityType(forClassWithGenerics(Observable.class, String.class));
 		HttpEntity> entity = resolveValueWithEmptyBody(type);
 
 		TestSubscriber.subscribe(RxJava1ObservableConverter.from(entity.getBody()))
@@ -163,7 +174,7 @@ public class HttpEntityArgumentResolverTests {
 
 	@Test
 	public void emptyBodyWithCompletableFuture() throws Exception {
-		ResolvableType type = httpEntity(forClassWithGenerics(CompletableFuture.class, String.class));
+		ResolvableType type = httpEntityType(forClassWithGenerics(CompletableFuture.class, String.class));
 		HttpEntity> entity = resolveValueWithEmptyBody(type);
 
 		entity.getBody().whenComplete((body, ex) -> {
@@ -175,7 +186,7 @@ public class HttpEntityArgumentResolverTests {
 	@Test
 	public void httpEntityWithStringBody() throws Exception {
 		String body = "line1";
-		ResolvableType type = httpEntity(String.class);
+		ResolvableType type = httpEntityType(String.class);
 		HttpEntity httpEntity = resolveValue(type, body);
 
 		assertEquals(this.request.getHeaders(), httpEntity.getHeaders());
@@ -185,7 +196,7 @@ public class HttpEntityArgumentResolverTests {
 	@Test
 	public void httpEntityWithMonoBody() throws Exception {
 		String body = "line1";
-		ResolvableType type = httpEntity(forClassWithGenerics(Mono.class, String.class));
+		ResolvableType type = httpEntityType(forClassWithGenerics(Mono.class, String.class));
 		HttpEntity> httpEntity = resolveValue(type, body);
 
 		assertEquals(this.request.getHeaders(), httpEntity.getHeaders());
@@ -195,7 +206,7 @@ public class HttpEntityArgumentResolverTests {
 	@Test
 	public void httpEntityWithSingleBody() throws Exception {
 		String body = "line1";
-		ResolvableType type = httpEntity(forClassWithGenerics(Single.class, String.class));
+		ResolvableType type = httpEntityType(forClassWithGenerics(Single.class, String.class));
 		HttpEntity> httpEntity = resolveValue(type, body);
 
 		assertEquals(this.request.getHeaders(), httpEntity.getHeaders());
@@ -205,7 +216,7 @@ public class HttpEntityArgumentResolverTests {
 	@Test
 	public void httpEntityWithCompletableFutureBody() throws Exception {
 		String body = "line1";
-		ResolvableType type = httpEntity(forClassWithGenerics(CompletableFuture.class, String.class));
+		ResolvableType type = httpEntityType(forClassWithGenerics(CompletableFuture.class, String.class));
 		HttpEntity> httpEntity = resolveValue(type, body);
 
 		assertEquals(this.request.getHeaders(), httpEntity.getHeaders());
@@ -215,7 +226,7 @@ public class HttpEntityArgumentResolverTests {
 	@Test
 	public void httpEntityWithFluxBody() throws Exception {
 		String body = "line1\nline2\nline3\n";
-		ResolvableType type = httpEntity(forClassWithGenerics(Flux.class, String.class));
+		ResolvableType type = httpEntityType(forClassWithGenerics(Flux.class, String.class));
 		HttpEntity> httpEntity = resolveValue(type, body);
 
 		assertEquals(this.request.getHeaders(), httpEntity.getHeaders());
@@ -235,25 +246,14 @@ public class HttpEntityArgumentResolverTests {
 	}
 
 
-	private ResolvableType httpEntity(Class bodyType) {
-		return httpEntity(ResolvableType.forClass(bodyType));
+	private ResolvableType httpEntityType(Class bodyType) {
+		return httpEntityType(ResolvableType.forClass(bodyType));
 	}
 
-	private ResolvableType httpEntity(ResolvableType type) {
+	private ResolvableType httpEntityType(ResolvableType type) {
 		return forClassWithGenerics(HttpEntity.class, type);
 	}
 
-	private HttpEntityArgumentResolver resolver() {
-		List> converters = new ArrayList<>();
-		converters.add(new CodecHttpMessageConverter<>(new StringDecoder()));
-
-		FormattingConversionService service = new DefaultFormattingConversionService();
-		service.addConverter(new MonoToCompletableFutureConverter());
-		service.addConverter(new ReactorToRxJava1Converter());
-
-		return new HttpEntityArgumentResolver(converters, service);
-	}
-
 	private void testSupports(ResolvableType type) {
 		MethodParameter parameter = this.testMethod.resolveParam(type);
 		assertTrue(this.resolver.supportsParameter(parameter));
diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/MessageConverterArgumentResolverTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/MessageConverterArgumentResolverTests.java
index 18b6c582a8..a2590f8a08 100644
--- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/MessageConverterArgumentResolverTests.java
+++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/MessageConverterArgumentResolverTests.java
@@ -83,7 +83,7 @@ public class MessageConverterArgumentResolverTests {
 
 	private MockServerHttpRequest request;
 
-	private ResolvableMethod testMethod = ResolvableMethod.on(this.getClass()).name("handle");
+	private ResolvableMethod testMethod = ResolvableMethod.onClass(this.getClass()).name("handle");
 
 
 	@Before
@@ -252,7 +252,7 @@ public class MessageConverterArgumentResolverTests {
 	@Ignore
 	public void parameterizedMethodArgument() throws Exception {
 		Class clazz = ConcreteParameterizedController.class;
-		MethodParameter param = ResolvableMethod.on(clazz).name("handleDto").resolveParam();
+		MethodParameter param = ResolvableMethod.onClass(clazz).name("handleDto").resolveParam();
 		SimpleBean simpleBean = resolveValue(param, "{\"name\" : \"Jad\"}");
 
 		assertEquals("Jad", simpleBean.getName());
diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/MessageConverterResultHandlerTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/MessageConverterResultHandlerTests.java
index cde0c86a90..256ea69891 100644
--- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/MessageConverterResultHandlerTests.java
+++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/MessageConverterResultHandlerTests.java
@@ -172,7 +172,7 @@ public class MessageConverterResultHandlerTests {
 
 
 	private MethodParameter returnType(ResolvableType bodyType) {
-		return ResolvableMethod.on(TestController.class).returning(bodyType).resolveReturnType();
+		return ResolvableMethod.onClass(TestController.class).returning(bodyType).resolveReturnType();
 	}
 
 	private AbstractMessageConverterResultHandler createResultHandler(HttpMessageConverter... converters) {
diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestBodyArgumentResolverTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestBodyArgumentResolverTests.java
index 3300637bb1..ecd98007eb 100644
--- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestBodyArgumentResolverTests.java
+++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestBodyArgumentResolverTests.java
@@ -79,7 +79,7 @@ public class RequestBodyArgumentResolverTests {
 
 	private MockServerHttpRequest request;
 
-	private ResolvableMethod testMethod = ResolvableMethod.on(this.getClass()).name("handle");
+	private ResolvableMethod testMethod = ResolvableMethod.onClass(this.getClass()).name("handle");
 
 
 	@Before
@@ -89,6 +89,17 @@ public class RequestBodyArgumentResolverTests {
 		this.exchange = new DefaultServerWebExchange(this.request, response, new MockWebSessionManager());
 	}
 
+	private RequestBodyArgumentResolver resolver() {
+		List> converters = new ArrayList<>();
+		converters.add(new CodecHttpMessageConverter<>(new StringDecoder()));
+
+		FormattingConversionService service = new DefaultFormattingConversionService();
+		service.addConverter(new MonoToCompletableFutureConverter());
+		service.addConverter(new ReactorToRxJava1Converter());
+
+		return new RequestBodyArgumentResolver(converters, service);
+	}
+
 
 	@Test
 	public void supports() throws Exception {
@@ -197,17 +208,6 @@ public class RequestBodyArgumentResolverTests {
 	}
 
 
-	private RequestBodyArgumentResolver resolver() {
-		List> converters = new ArrayList<>();
-		converters.add(new CodecHttpMessageConverter<>(new StringDecoder()));
-
-		FormattingConversionService service = new DefaultFormattingConversionService();
-		service.addConverter(new MonoToCompletableFutureConverter());
-		service.addConverter(new ReactorToRxJava1Converter());
-
-		return new RequestBodyArgumentResolver(converters, service);
-	}
-
 	private  T resolveValue(MethodParameter param, String body) {
 		this.request.writeWith(Flux.just(dataBuffer(body)));
 		Mono result = this.resolver.readBody(param, true, this.exchange);
@@ -221,9 +221,9 @@ public class RequestBodyArgumentResolverTests {
 		return (T) value;
 	}
 
-	private  T resolveValueWithEmptyBody(ResolvableType type, boolean required) {
+	private  T resolveValueWithEmptyBody(ResolvableType bodyType, boolean isRequired) {
 		this.request.writeWith(Flux.empty());
-		MethodParameter param = this.testMethod.resolveParam(type, requestBody(required));
+		MethodParameter param = this.testMethod.resolveParam(bodyType, requestBody(isRequired));
 		Mono result = this.resolver.resolveArgument(param, new ExtendedModelMap(), this.exchange);
 		Object value = result.block(Duration.ofSeconds(5));
 
diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandlerTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandlerTests.java
index 93860f2a16..22a878cbea 100644
--- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandlerTests.java
+++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandlerTests.java
@@ -199,7 +199,7 @@ public class ResponseEntityResultHandlerTests {
 	}
 
 	private HandlerResult handlerResult(Object returnValue, ResolvableType type) {
-		MethodParameter param = ResolvableMethod.on(TestController.class).returning(type).resolveReturnType();
+		MethodParameter param = ResolvableMethod.onClass(TestController.class).returning(type).resolveReturnType();
 		return new HandlerResult(new TestController(), returnValue, param);
 	}
 
diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/view/HttpMessageConverterViewTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/view/HttpMessageConverterViewTests.java
index 4fb874abc5..7af0bb3849 100644
--- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/view/HttpMessageConverterViewTests.java
+++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/view/HttpMessageConverterViewTests.java
@@ -72,7 +72,7 @@ public class HttpMessageConverterViewTests {
 
 	@Before
 	public void setup() throws Exception {
-		MethodParameter param = ResolvableMethod.on(this.getClass()).name("handle").resolveReturnType();
+		MethodParameter param = ResolvableMethod.onClass(this.getClass()).name("handle").resolveReturnType();
 		this.result = new HandlerResult(this, null, param, this.model);
 	}
 
diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandlerTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandlerTests.java
index a06c70cd23..61f9720a28 100644
--- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandlerTests.java
+++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandlerTests.java
@@ -104,7 +104,7 @@ public class ViewResolutionResultHandlerTests {
 		testSupports(ResolvableType.forClass(TestBean.class), true);
 		testSupports(ResolvableType.forClass(Integer.class), false);
 
-		testSupports(ResolvableMethod.on(TestController.class).annotated(ModelAttribute.class), true);
+		testSupports(ResolvableMethod.onClass(TestController.class).annotated(ModelAttribute.class), true);
 	}
 
 	@Test
@@ -153,7 +153,7 @@ public class ViewResolutionResultHandlerTests {
 		String responseBody = "account: {id=123, testBean=TestBean[name=Joe]}";
 		testHandle("/account", returnType, returnValue, responseBody, resolver);
 
-		testHandle("/account", ResolvableMethod.on(TestController.class).annotated(ModelAttribute.class),
+		testHandle("/account", ResolvableMethod.onClass(TestController.class).annotated(ModelAttribute.class),
 				99L, "account: {id=123, num=99}", resolver);
 	}
 
@@ -239,7 +239,7 @@ public class ViewResolutionResultHandlerTests {
 
 
 	private MethodParameter returnType(ResolvableType type) {
-		return ResolvableMethod.on(TestController.class).returning(type).resolveReturnType();
+		return ResolvableMethod.onClass(TestController.class).returning(type).resolveReturnType();
 	}
 
 	private ViewResolutionResultHandler createResultHandler(ViewResolver... resolvers) {
@@ -258,7 +258,7 @@ public class ViewResolutionResultHandlerTests {
 	}
 
 	private void testSupports(ResolvableType type, boolean result) {
-		testSupports(ResolvableMethod.on(TestController.class).returning(type), result);
+		testSupports(ResolvableMethod.onClass(TestController.class).returning(type), result);
 	}
 
 	private void testSupports(ResolvableMethod resolvableMethod, boolean result) {
@@ -271,7 +271,7 @@ public class ViewResolutionResultHandlerTests {
 	private void testHandle(String path, ResolvableType returnType, Object returnValue,
 			String responseBody, ViewResolver... resolvers) throws URISyntaxException {
 
-		testHandle(path,  ResolvableMethod.on(TestController.class).returning(returnType),
+		testHandle(path,  ResolvableMethod.onClass(TestController.class).returning(returnType),
 				returnValue, responseBody, resolvers);
 	}