Spring AntPathMatcher

Spring AntPathMatcher

AntPathMatcher是用来对资源路径或者url的字符串做匹配使用的。采用的是Ant风格的格式

Ant风格的资源地址支持3中匹配

  • ?:匹配文件名中的一个字符
  • *:匹配文件中的任意字符
  • :匹配多层路径 如下示例: classpath:com/con?.xml:匹配com路径下的com/conf.xml、com/cont.xml等文件 classpath:com/*.xml:匹配com路径下的所有的xml文件 classpath:com//a.xml:匹配com路径下其他文件夹下的所有的a.xml文件

AntPathMatcher的主要属性如下:

//默认路径分隔符
public static final String DEFAULT_PATH_SEPARATOR = "/";

private static final int CACHE_TURNOFF_THRESHOLD = 65536;
//正则表达式
private static final Pattern VARIABLE_PATTERN = Pattern.compile("\\{[^/]+?}");
//通配符
private static final char[] WILDCARD_CHARS = { '*', '?', '{' };
private String pathSeparator;

private PathSeparatorPatternCache pathSeparatorPatternCache;

private boolean caseSensitive = true;
//默认不
private boolean trimTokens = false;
//用来定义是否缓存分词
@Nullable
private volatile Boolean cachePatterns;
//用来缓存规则的分词
private final Map tokenizedPatternCache = new ConcurrentHashMap<>(256);

final Map stringMatcherCache = new ConcurrentHashMap<>(256);

其中Spring中用到最多的方法就是match()方法啦,

//用来匹配路径字符串是否满足给定的规则
@Override
public boolean match(String pattern, String path) {
    return doMatch(pattern, path, true, null);
}
protected boolean doMatch(String pattern, @Nullable String path, boolean fullMatch,
        @Nullable Map uriTemplateVariables) {
    //判断path是null 或者pattern和path的首字符是否同时为设置的分隔符,如果为null或者不一致则直接返回false
    if (path == null || path.startsWith(this.pathSeparator) != pattern.startsWith(this.pathSeparator)) {
        return false;
    }
    //对规则进行分词
    String[] pattDirs = tokenizePattern(pattern);
    if (fullMatch && this.caseSensitive && !isPotentialMatch(path, pattDirs)) {
        return false;
    }

    String[] pathDirs = tokenizePath(path);
    int pattIdxStart = 0;
    int pattIdxEnd = pattDirs.length - 1;
    int pathIdxStart = 0;
    int pathIdxEnd = pathDirs.length - 1;

    // Match all elements up to the first **
    while (pattIdxStart  pathIdxEnd) {
        // Path is exhausted, only match if rest of pattern is * or **'s
        if (pattIdxStart > pattIdxEnd) {
            return (pattern.endsWith(this.pathSeparator) == path.endsWith(this.pathSeparator));
        }
        if (!fullMatch) {
            return true;
        }
        if (pattIdxStart == pattIdxEnd && pattDirs[pattIdxStart].equals("*") && path.endsWith(this.pathSeparator)) {
            return true;
        }
        for (int i = pattIdxStart; i  pattIdxEnd) {
        // String not exhausted, but pattern is. Failure.
        return false;
    }
    else if (!fullMatch && "**".equals(pattDirs[pattIdxStart])) {
        // Path start definitely matches due to "**" part in pattern.
        return true;
    }

    // up to last '**'
    while (pattIdxStart  pathIdxEnd) {
        // String is exhausted
        for (int i = pattIdxStart; i

对规则进行分词

//对规则进行分词
protected String[] tokenizePattern(String pattern) {
    String[] tokenized = null;
    Boolean cachePatterns = this.cachePatterns;
    //当cachePatterns为null或者为true时,表示缓存分词,需要首先从map对象中获取
    if (cachePatterns == null || cachePatterns.booleanValue()) {
    //从缓存中获取分词
        tokenized = this.tokenizedPatternCache.get(pattern);
    }
    //缓存中不存在该分词是
    if (tokenized == null) {
        tokenized = tokenizePath(pattern);
        //当cachePatterns为null且tokenizedPatternCache对象中缓存的对象大于等于65536时,将缓存对象清空
        if (cachePatterns == null && this.tokenizedPatternCache.size() >= CACHE_TURNOFF_THRESHOLD) {
            // Try to adapt to the runtime situation that we're encountering:
            // There are obviously too many different patterns coming in here...
            // So let's turn off the cache since the patterns are unlikely to be reoccurring.
            //缓存对象清空
            deactivatePatternCache();
            return tokenized;
        }
        //将分词放入缓存中
        if (cachePatterns == null || cachePatterns.booleanValue()) {
            this.tokenizedPatternCache.put(pattern, tokenized);
        }
    }
    return tokenized;
}
//匹配字符串path是否以pattern开头
@Override
public boolean matchStart(String pattern, String path) {
   return doMatch(pattern, path, false, null);
}

Original: https://www.cnblogs.com/haizhilangzi/p/12805150.html
Author: 海之浪子
Title: Spring AntPathMatcher

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/581070/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球