From 525fc7a27e57505806e0860310543946a3b053ad Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Fri, 9 Dec 2022 11:27:03 +0000 Subject: [PATCH] Optimize object creation PartialMatchHelper Closes gh-29667 --- .../RequestMappingInfoHandlerMapping.java | 19 +++++++++++-------- ...RequestMappingInfoHandlerMappingTests.java | 14 ++++++++++++-- .../RequestMappingInfoHandlerMapping.java | 6 +++++- ...RequestMappingInfoHandlerMappingTests.java | 14 +++++++++++++- 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMapping.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMapping.java index 29ca83b73a8..d7b287a3472 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMapping.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMapping.java @@ -36,6 +36,7 @@ import org.springframework.http.MediaType; import org.springframework.http.server.PathContainer; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.method.HandlerMethod; @@ -165,8 +166,11 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe protected HandlerMethod handleNoMatch(Set infos, ServerWebExchange exchange) throws Exception { - PartialMatchHelper helper = new PartialMatchHelper(infos, exchange); + if (CollectionUtils.isEmpty(infos)) { + return null; + } + PartialMatchHelper helper = new PartialMatchHelper(infos, exchange); if (helper.isEmpty()) { return null; } @@ -218,15 +222,14 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe private final List partialMatches = new ArrayList<>(); - - public PartialMatchHelper(Set infos, ServerWebExchange exchange) { - this.partialMatches.addAll(infos.stream(). - filter(info -> info.getPatternsCondition().getMatchingCondition(exchange) != null). - map(info -> new PartialMatch(info, exchange)). - collect(Collectors.toList())); + PartialMatchHelper(Set infos, ServerWebExchange exchange) { + for (RequestMappingInfo info : infos) { + if (info.getPatternsCondition().getMatchingCondition(exchange) != null) { + this.partialMatches.add(new PartialMatch(info, exchange)); + } + } } - /** * Whether there are any partial matches. */ diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMappingTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMappingTests.java index cbc923abe1b..628c9dc407e 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMappingTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMappingTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.EnumSet; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -334,9 +335,18 @@ public class RequestMappingInfoHandlerMappingTests { assertThat(umtse.getResponseHeaders().getAcceptPatch()).containsExactly(mediaType); }) .verify(); - } + @Test // gh-29611 + public void handleNoMatchWithoutPartialMatches() throws Exception { + ServerWebExchange exchange = MockServerWebExchange.from(post("/non-existent")); + + HandlerMethod handlerMethod = this.handlerMapping.handleNoMatch(new HashSet<>(), exchange); + assertThat(handlerMethod).isNull(); + + handlerMethod = this.handlerMapping.handleNoMatch(null, exchange); + assertThat(handlerMethod).isNull(); + } @SuppressWarnings("unchecked") private void assertError(Mono mono, final Class exceptionClass, final Consumer consumer) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMapping.java index 8a52d52b7ba..99131d2bd34 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMapping.java @@ -241,6 +241,10 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe protected HandlerMethod handleNoMatch( Set infos, String lookupPath, HttpServletRequest request) throws ServletException { + if (CollectionUtils.isEmpty(infos)) { + return null; + } + PartialMatchHelper helper = new PartialMatchHelper(infos, request); if (helper.isEmpty()) { return null; @@ -291,7 +295,7 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe private final List partialMatches = new ArrayList<>(); - public PartialMatchHelper(Set infos, HttpServletRequest request) { + PartialMatchHelper(Set infos, HttpServletRequest request) { for (RequestMappingInfo info : infos) { if (info.getActivePatternsCondition().getMatchingCondition(request) != null) { this.partialMatches.add(new PartialMatch(info, request)); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMappingTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMappingTests.java index aa31dc21b81..f0f8eddbdd1 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMappingTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMappingTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. @@ -389,6 +389,18 @@ class RequestMappingInfoHandlerMappingTests { assertThat(uriVariables.get("cars")).isEqualTo("cars"); } + @PathPatternsParameterizedTest // gh-29611 + void handleNoMatchWithoutPartialMatches(TestRequestMappingInfoHandlerMapping mapping) throws Exception { + String path = "/non-existent"; + MockHttpServletRequest request = new MockHttpServletRequest("GET", path); + + HandlerMethod handlerMethod = mapping.handleNoMatch(new HashSet<>(), path, request); + assertThat(handlerMethod).isNull(); + + handlerMethod = mapping.handleNoMatch(null, path, request); + assertThat(handlerMethod).isNull(); + } + private HandlerMethod getHandler( TestRequestMappingInfoHandlerMapping mapping, MockHttpServletRequest request) throws Exception {