Skip to content

Commit 2ac08af

Browse files
committed
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
1 parent ef550c4 commit 2ac08af

File tree

1 file changed

+12
-13
lines changed

1 file changed

+12
-13
lines changed

spring-web/src/main/java/org/springframework/web/util/ParsingPathMatcher.java

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@
1717
package org.springframework.web.util;
1818

1919
import java.util.Comparator;
20-
import java.util.HashMap;
2120
import java.util.Map;
21+
import java.util.concurrent.ConcurrentHashMap;
22+
import java.util.concurrent.ConcurrentMap;
2223

2324
import org.springframework.util.PathMatcher;
2425
import org.springframework.web.util.patterns.PathPattern;
@@ -39,13 +40,11 @@
3940
*/
4041
public class ParsingPathMatcher implements PathMatcher {
4142

42-
Map<String, PathPattern> cache = new HashMap<>();
43+
private final ConcurrentMap<String, PathPattern> cache =
44+
new ConcurrentHashMap<>(64);
4345

44-
PathPatternParser parser;
45-
46-
public ParsingPathMatcher() {
47-
parser = new PathPatternParser();
48-
}
46+
private static final ThreadLocal<PathPatternParser> PARSER
47+
= ThreadLocal.withInitial(() -> new PathPatternParser());
4948

5049
@Override
5150
public boolean match(String pattern, String path) {
@@ -84,10 +83,10 @@ public Comparator<String> getPatternComparator(String path) {
8483

8584
class PathPatternStringComparatorConsideringPath implements Comparator<String> {
8685

87-
PatternComparatorConsideringPath ppcp;
86+
private final PatternComparatorConsideringPath ppcp;
8887

8988
public PathPatternStringComparatorConsideringPath(String path) {
90-
ppcp = new PatternComparatorConsideringPath(path);
89+
this.ppcp = new PatternComparatorConsideringPath(path);
9190
}
9291

9392
@Override
@@ -100,7 +99,7 @@ else if (o2 == null) {
10099
}
101100
PathPattern p1 = getPathPattern(o1);
102101
PathPattern p2 = getPathPattern(o2);
103-
return ppcp.compare(p1, p2);
102+
return this.ppcp.compare(p1, p2);
104103
}
105104

106105
}
@@ -112,10 +111,10 @@ public boolean isPattern(String path) {
112111
}
113112

114113
private PathPattern getPathPattern(String pattern) {
115-
PathPattern pathPattern = cache.get(pattern);
114+
PathPattern pathPattern = this.cache.get(pattern);
116115
if (pathPattern == null) {
117-
pathPattern = parser.parse(pattern);
118-
cache.put(pattern, pathPattern);
116+
pathPattern = PARSER.get().parse(pattern);
117+
this.cache.put(pattern, pathPattern);
119118
}
120119
return pathPattern;
121120
}

0 commit comments

Comments
 (0)