From 34c3e821ddb25e90f1e8ad90aac55f68a6f2f195 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Mon, 10 Sep 2012 16:57:10 -0400 Subject: [PATCH] Cache AntPathStringMatcher instances AntPathMatcher now caches AntPathStringMatcher instances by pattern thus avoiding java.util.regex.Pattern recompilation. Issue: SPR-9749 --- .../springframework/util/AntPathMatcher.java | 14 +++++++++++--- .../util/AntPathStringMatcher.java | 17 ++++++----------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java b/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java index 5bf54abb54..dd69dee004 100644 --- a/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java +++ b/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2012 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. @@ -19,6 +19,7 @@ package org.springframework.util; import java.util.Comparator; import java.util.LinkedHashMap; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -53,6 +54,9 @@ public class AntPathMatcher implements PathMatcher { private String pathSeparator = DEFAULT_PATH_SEPARATOR; + private final Map stringMatcherCache = + new ConcurrentHashMap(); + /** Set the path separator to use for pattern parsing. Default is "/", as in Ant. */ public void setPathSeparator(String pathSeparator) { @@ -216,8 +220,12 @@ public class AntPathMatcher implements PathMatcher { * @return true if the string matches against the pattern, or false otherwise. */ private boolean matchStrings(String pattern, String str, Map uriTemplateVariables) { - AntPathStringMatcher matcher = new AntPathStringMatcher(pattern, str, uriTemplateVariables); - return matcher.matchStrings(); + AntPathStringMatcher matcher = this.stringMatcherCache.get(pattern); + if (matcher == null) { + matcher = new AntPathStringMatcher(pattern); + this.stringMatcherCache.put(pattern, matcher); + } + return matcher.matchStrings(str, uriTemplateVariables); } /** diff --git a/spring-core/src/main/java/org/springframework/util/AntPathStringMatcher.java b/spring-core/src/main/java/org/springframework/util/AntPathStringMatcher.java index 7c093a519d..424b60930e 100644 --- a/spring-core/src/main/java/org/springframework/util/AntPathStringMatcher.java +++ b/spring-core/src/main/java/org/springframework/util/AntPathStringMatcher.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2012 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. @@ -41,16 +41,11 @@ class AntPathStringMatcher { private final Pattern pattern; - private String str; - private final List variableNames = new LinkedList(); - private final Map uriTemplateVariables; /** Construct a new instance of the AntPatchStringMatcher. */ - AntPathStringMatcher(String pattern, String str, Map uriTemplateVariables) { - this.str = str; - this.uriTemplateVariables = uriTemplateVariables; + AntPathStringMatcher(String pattern) { this.pattern = createPattern(pattern); } @@ -100,14 +95,14 @@ class AntPathStringMatcher { * * @return true if the string matches against the pattern, or false otherwise. */ - public boolean matchStrings() { + public boolean matchStrings(String str, Map uriTemplateVariables) { Matcher matcher = pattern.matcher(str); if (matcher.matches()) { if (uriTemplateVariables != null) { // SPR-8455 - Assert.isTrue(variableNames.size() == matcher.groupCount(), - "The number of capturing groups in the pattern segment " + pattern + - " does not match the number of URI template variables it defines, which can occur if " + + Assert.isTrue(variableNames.size() == matcher.groupCount(), + "The number of capturing groups in the pattern segment " + pattern + + " does not match the number of URI template variables it defines, which can occur if " + " capturing groups are used in a URI template regex. Use non-capturing groups instead."); for (int i = 1; i <= matcher.groupCount(); i++) { String name = this.variableNames.get(i - 1);