Threadsafe use of pattern parser in ParsingPathMatcher
This commit ensures that the `PathPatternParser` and the associated cache map are used in a threadsafe fashion, since the PathMatcher instance can be used for concurrent requests. Issue: SPR-15246
This commit is contained in:
@@ -17,8 +17,9 @@
|
||||
package org.springframework.web.util;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import org.springframework.util.PathMatcher;
|
||||
import org.springframework.web.util.patterns.PathPattern;
|
||||
@@ -39,13 +40,11 @@ import org.springframework.web.util.patterns.PatternComparatorConsideringPath;
|
||||
*/
|
||||
public class ParsingPathMatcher implements PathMatcher {
|
||||
|
||||
Map<String, PathPattern> cache = new HashMap<>();
|
||||
private final ConcurrentMap<String, PathPattern> cache =
|
||||
new ConcurrentHashMap<>(64);
|
||||
|
||||
PathPatternParser parser;
|
||||
|
||||
public ParsingPathMatcher() {
|
||||
parser = new PathPatternParser();
|
||||
}
|
||||
private static final ThreadLocal<PathPatternParser> PARSER
|
||||
= ThreadLocal.withInitial(() -> new PathPatternParser());
|
||||
|
||||
@Override
|
||||
public boolean match(String pattern, String path) {
|
||||
@@ -84,10 +83,10 @@ public class ParsingPathMatcher implements PathMatcher {
|
||||
|
||||
class PathPatternStringComparatorConsideringPath implements Comparator<String> {
|
||||
|
||||
PatternComparatorConsideringPath ppcp;
|
||||
private final PatternComparatorConsideringPath ppcp;
|
||||
|
||||
public PathPatternStringComparatorConsideringPath(String path) {
|
||||
ppcp = new PatternComparatorConsideringPath(path);
|
||||
this.ppcp = new PatternComparatorConsideringPath(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -100,7 +99,7 @@ public class ParsingPathMatcher implements PathMatcher {
|
||||
}
|
||||
PathPattern p1 = getPathPattern(o1);
|
||||
PathPattern p2 = getPathPattern(o2);
|
||||
return ppcp.compare(p1, p2);
|
||||
return this.ppcp.compare(p1, p2);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -112,10 +111,10 @@ public class ParsingPathMatcher implements PathMatcher {
|
||||
}
|
||||
|
||||
private PathPattern getPathPattern(String pattern) {
|
||||
PathPattern pathPattern = cache.get(pattern);
|
||||
PathPattern pathPattern = this.cache.get(pattern);
|
||||
if (pathPattern == null) {
|
||||
pathPattern = parser.parse(pattern);
|
||||
cache.put(pattern, pathPattern);
|
||||
pathPattern = PARSER.get().parse(pattern);
|
||||
this.cache.put(pattern, pathPattern);
|
||||
}
|
||||
return pathPattern;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user