Skip to content

Commit 34c3e82

Browse files
committed
Cache AntPathStringMatcher instances
AntPathMatcher now caches AntPathStringMatcher instances by pattern thus avoiding java.util.regex.Pattern recompilation. Issue: SPR-9749
1 parent 0a877af commit 34c3e82

File tree

2 files changed

+17
-14
lines changed

2 files changed

+17
-14
lines changed

spring-core/src/main/java/org/springframework/util/AntPathMatcher.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2010 the original author or authors.
2+
* Copyright 2002-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
1919
import java.util.Comparator;
2020
import java.util.LinkedHashMap;
2121
import java.util.Map;
22+
import java.util.concurrent.ConcurrentHashMap;
2223
import java.util.regex.Matcher;
2324
import java.util.regex.Pattern;
2425

@@ -53,6 +54,9 @@ public class AntPathMatcher implements PathMatcher {
5354

5455
private String pathSeparator = DEFAULT_PATH_SEPARATOR;
5556

57+
private final Map<String, AntPathStringMatcher> stringMatcherCache =
58+
new ConcurrentHashMap<String, AntPathStringMatcher>();
59+
5660

5761
/** Set the path separator to use for pattern parsing. Default is "/", as in Ant. */
5862
public void setPathSeparator(String pathSeparator) {
@@ -216,8 +220,12 @@ else if (!fullMatch && "**".equals(pattDirs[pattIdxStart])) {
216220
* @return <code>true</code> if the string matches against the pattern, or <code>false</code> otherwise.
217221
*/
218222
private boolean matchStrings(String pattern, String str, Map<String, String> uriTemplateVariables) {
219-
AntPathStringMatcher matcher = new AntPathStringMatcher(pattern, str, uriTemplateVariables);
220-
return matcher.matchStrings();
223+
AntPathStringMatcher matcher = this.stringMatcherCache.get(pattern);
224+
if (matcher == null) {
225+
matcher = new AntPathStringMatcher(pattern);
226+
this.stringMatcherCache.put(pattern, matcher);
227+
}
228+
return matcher.matchStrings(str, uriTemplateVariables);
221229
}
222230

223231
/**

spring-core/src/main/java/org/springframework/util/AntPathStringMatcher.java

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2009 the original author or authors.
2+
* Copyright 2002-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -41,16 +41,11 @@ class AntPathStringMatcher {
4141

4242
private final Pattern pattern;
4343

44-
private String str;
45-
4644
private final List<String> variableNames = new LinkedList<String>();
4745

48-
private final Map<String, String> uriTemplateVariables;
4946

5047
/** Construct a new instance of the <code>AntPatchStringMatcher</code>. */
51-
AntPathStringMatcher(String pattern, String str, Map<String, String> uriTemplateVariables) {
52-
this.str = str;
53-
this.uriTemplateVariables = uriTemplateVariables;
48+
AntPathStringMatcher(String pattern) {
5449
this.pattern = createPattern(pattern);
5550
}
5651

@@ -100,14 +95,14 @@ private String quote(String s, int start, int end) {
10095
*
10196
* @return <code>true</code> if the string matches against the pattern, or <code>false</code> otherwise.
10297
*/
103-
public boolean matchStrings() {
98+
public boolean matchStrings(String str, Map<String, String> uriTemplateVariables) {
10499
Matcher matcher = pattern.matcher(str);
105100
if (matcher.matches()) {
106101
if (uriTemplateVariables != null) {
107102
// SPR-8455
108-
Assert.isTrue(variableNames.size() == matcher.groupCount(),
109-
"The number of capturing groups in the pattern segment " + pattern +
110-
" does not match the number of URI template variables it defines, which can occur if " +
103+
Assert.isTrue(variableNames.size() == matcher.groupCount(),
104+
"The number of capturing groups in the pattern segment " + pattern +
105+
" does not match the number of URI template variables it defines, which can occur if " +
111106
" capturing groups are used in a URI template regex. Use non-capturing groups instead.");
112107
for (int i = 1; i <= matcher.groupCount(); i++) {
113108
String name = this.variableNames.get(i - 1);

0 commit comments

Comments
 (0)