Skip to content

Commit fac35eb

Browse files
committed
Remove PathPatternRegistry
1 parent e7b77cb commit fac35eb

File tree

9 files changed

+131
-446
lines changed

9 files changed

+131
-446
lines changed

spring-webflux/src/main/java/org/springframework/web/reactive/handler/AbstractUrlHandlerMapping.java

Lines changed: 57 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
package org.springframework.web.reactive.handler;
1818

1919
import java.util.Collections;
20+
import java.util.Comparator;
21+
import java.util.LinkedHashMap;
2022
import java.util.Map;
2123

2224
import reactor.core.publisher.Mono;
@@ -25,6 +27,7 @@
2527
import org.springframework.http.server.reactive.PathContainer;
2628
import org.springframework.lang.Nullable;
2729
import org.springframework.util.Assert;
30+
import org.springframework.util.StringUtils;
2831
import org.springframework.web.server.ServerWebExchange;
2932
import org.springframework.web.util.pattern.PathPattern;
3033

@@ -51,8 +54,7 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping {
5154

5255
private boolean lazyInitHandlers = false;
5356

54-
@Nullable
55-
private PathPatternRegistry<Object> patternRegistry;
57+
private final Map<PathPattern, Object> handlerMap = new LinkedHashMap<>();
5658

5759

5860
/**
@@ -70,12 +72,12 @@ public void setLazyInitHandlers(boolean lazyInitHandlers) {
7072
}
7173

7274
/**
73-
* Return the registered handlers as an unmodifiable Map, with the registered path
74-
* pattern as key and the handler object (or handler bean name in case of a lazy-init handler)
75-
* as value.
75+
* Return a read-only view of registered path patterns and handlers which may
76+
* may be an actual handler instance or the bean name of lazily initialized
77+
* handler.
7678
*/
7779
public final Map<PathPattern, Object> getHandlerMap() {
78-
return (this.patternRegistry != null ? this.patternRegistry.getPatternsMap() : Collections.emptyMap());
80+
return Collections.unmodifiableMap(this.handlerMap);
7981
}
8082

8183

@@ -111,25 +113,26 @@ else if (handler == null && logger.isTraceEnabled()) {
111113
* @see org.springframework.web.util.pattern.PathPattern
112114
*/
113115
@Nullable
114-
protected Object lookupHandler(PathContainer lookupPath, ServerWebExchange exchange) throws Exception {
115-
if (this.patternRegistry != null) {
116-
PathMatchResult<Object> bestMatch = this.patternRegistry.findFirstMatch(lookupPath);
117-
if (bestMatch != null) {
118-
if (logger.isDebugEnabled()) {
119-
logger.debug("Matching patterns for request [" + lookupPath + "] are " + bestMatch);
120-
}
121-
PathContainer pathWithinMapping = bestMatch.getPattern().extractPathWithinPattern(lookupPath);
122-
Object handler = bestMatch.getHandler();
123-
return handleMatch(handler, bestMatch.getPattern(), pathWithinMapping, exchange);
124-
}
125-
}
126-
127-
// No handler found...
128-
return null;
116+
protected Object lookupHandler(PathContainer lookupPath, ServerWebExchange exchange)
117+
throws Exception {
118+
119+
return this.handlerMap.entrySet().stream()
120+
.filter(entry -> entry.getKey().matches(lookupPath))
121+
.sorted(Comparator.comparing(Map.Entry::getKey))
122+
.findFirst()
123+
.map(entry -> {
124+
PathPattern pattern = entry.getKey();
125+
if (logger.isDebugEnabled()) {
126+
logger.debug("Matching pattern for request [" + lookupPath + "] is " + pattern);
127+
}
128+
PathContainer pathWithinMapping = pattern.extractPathWithinPattern(lookupPath);
129+
return handleMatch(entry.getValue(), pattern, pathWithinMapping, exchange);
130+
})
131+
.orElse(null);
129132
}
130133

131134
private Object handleMatch(Object handler, PathPattern bestMatch, PathContainer pathWithinMapping,
132-
ServerWebExchange exchange) throws Exception {
135+
ServerWebExchange exchange) {
133136

134137
// Bean name or resolved handler?
135138
if (handler instanceof String) {
@@ -152,10 +155,9 @@ private Object handleMatch(Object handler, PathPattern bestMatch, PathContainer
152155
* for example to enforce specific preconditions expressed in URL mappings.
153156
* @param handler the handler object to validate
154157
* @param exchange current exchange
155-
* @throws Exception if validation failed
156158
*/
157159
@SuppressWarnings("UnusedParameters")
158-
protected void validateHandler(Object handler, ServerWebExchange exchange) throws Exception {
160+
protected void validateHandler(Object handler, ServerWebExchange exchange) {
159161
}
160162

161163
/**
@@ -165,7 +167,9 @@ protected void validateHandler(Object handler, ServerWebExchange exchange) throw
165167
* @throws BeansException if the handler couldn't be registered
166168
* @throws IllegalStateException if there is a conflicting handler registered
167169
*/
168-
protected void registerHandler(String[] urlPaths, String beanName) throws BeansException, IllegalStateException {
170+
protected void registerHandler(String[] urlPaths, String beanName)
171+
throws BeansException, IllegalStateException {
172+
169173
Assert.notNull(urlPaths, "URL path array must not be null");
170174
for (String urlPath : urlPaths) {
171175
registerHandler(urlPath, beanName);
@@ -180,11 +184,26 @@ protected void registerHandler(String[] urlPaths, String beanName) throws BeansE
180184
* @throws BeansException if the handler couldn't be registered
181185
* @throws IllegalStateException if there is a conflicting handler registered
182186
*/
183-
protected void registerHandler(String urlPath, Object handler) throws BeansException, IllegalStateException {
187+
protected void registerHandler(String urlPath, Object handler)
188+
throws BeansException, IllegalStateException {
189+
184190
Assert.notNull(urlPath, "URL path must not be null");
185191
Assert.notNull(handler, "Handler object must not be null");
186192
Object resolvedHandler = handler;
187193

194+
// Parse path pattern
195+
urlPath = prependLeadingSlash(urlPath);
196+
PathPattern pattern = getPathPatternParser().parse(urlPath);
197+
if (this.handlerMap.containsKey(pattern)) {
198+
Object existingHandler = this.handlerMap.get(pattern);
199+
if (existingHandler != null) {
200+
if (existingHandler != resolvedHandler) {
201+
throw new IllegalStateException(
202+
"Cannot map " + getHandlerDescription(handler) + " to [" + urlPath + "]: " +
203+
"there is already " + getHandlerDescription(existingHandler) + " mapped.");
204+
}
205+
}
206+
}
188207

189208
// Eagerly resolve handler if referencing singleton via name.
190209
if (!this.lazyInitHandlers && handler instanceof String) {
@@ -193,32 +212,26 @@ protected void registerHandler(String urlPath, Object handler) throws BeansExcep
193212
resolvedHandler = obtainApplicationContext().getBean(handlerName);
194213
}
195214
}
196-
if (this.patternRegistry == null) {
197-
this.patternRegistry = new PathPatternRegistry<>(getPathPatternParser());
215+
216+
// Register resolved handler
217+
this.handlerMap.put(pattern, resolvedHandler);
218+
if (logger.isInfoEnabled()) {
219+
logger.info("Mapped URL path [" + urlPath + "] onto " + getHandlerDescription(handler));
198220
}
221+
}
199222

200-
Map<PathPattern, Object> patternsMap = this.patternRegistry.getPatternsMap();
201-
if (patternsMap.containsKey(urlPath)) {
202-
Object mappedHandler = patternsMap.get(urlPath);
203-
if (mappedHandler != null) {
204-
if (mappedHandler != resolvedHandler) {
205-
throw new IllegalStateException(
206-
"Cannot map " + getHandlerDescription(handler) + " to URL path [" + urlPath +
207-
"]: There is already " + getHandlerDescription(mappedHandler) + " mapped.");
208-
}
209-
}
223+
private static String prependLeadingSlash(String pattern) {
224+
if (StringUtils.hasLength(pattern) && !pattern.startsWith("/")) {
225+
return "/" + pattern;
210226
}
211227
else {
212-
this.patternRegistry.register(urlPath, resolvedHandler);
213-
}
214-
215-
if (logger.isInfoEnabled()) {
216-
logger.info("Mapped URL path [" + urlPath + "] onto " + getHandlerDescription(handler));
228+
return pattern;
217229
}
218230
}
219231

220232
private String getHandlerDescription(Object handler) {
221-
return "handler " + (handler instanceof String ? "'" + handler + "'" : "of type [" + handler.getClass() + "]");
233+
return "handler " + (handler instanceof String ?
234+
"'" + handler + "'" : "of type [" + handler.getClass() + "]");
222235
}
223236

224237
}

spring-webflux/src/main/java/org/springframework/web/reactive/handler/PathMatchResult.java

Lines changed: 0 additions & 77 deletions
This file was deleted.

0 commit comments

Comments
 (0)