Spring源码学习-含有通配符路径解析(上)

如果路径包含通配符(?,*,**)spring是怎么处理的?如果是以classpath*开头的又是如何呢?

先测试分析包含通配符(?)的。

正如测试用例所写,实际是找不到该Bean的。这又是为什么?Spring不是支持通配符吗?FileSystemXmlApplicationContext的注释里也提到了通配符的情况:

从代码中寻找答案。回到上回的else分支中,因为包含通配符,所以进入第一个子分支。

此方法传入的完整的没有处理的路径,从第一行开始,就开始分步处理解析传入的路径,首先是决定“根”路径: determineRootDir(locationPattern)

这个“根”,就是不包含通配符的最长的部分,以我们的路径为例,这个“根”本来应该是: D:\\workspace-home\\spring-custom\\src\\main\\resources\\spring\\,但是实际上,从determineRootDir的实现可以看出:

首先,先找到冒号:索引位,赋值给 prefixEnd。

然后,在从冒号开始到最后的字符串中,循环判断是否包含通配符,网站空间,如果包含,则截断最后一个由"/"分割的部分,例如:在我们路径中,就是最后的ap?-context.xml这一段。再循环判断剩下的部分,直到剩下的路径中都不包含通配符。

如果查找完成后,rootDirEnd=0了,则将之前赋值的prefixEnd的值赋给rootDirEnd,也就是":"所在的索引位。

最后,服务器空间,将字符串从开始截断rootDirEnd。

我们的问题,就出在关键的第二步,Spring这里只在字符串中查找"/",并没有支持"\\"这样的路径分割方式,所以,自然找不到"\\",rootDirEnd = -1 + 1 = 0。所以循环后,阶段出来的路径就是D:,自然Spring会找不到配置文件,容器无法初始化。

基于以上分析,我们将路径修改为:D:/workspace-home/spring-custom/src/main/resources/spring/ap?-context.xml,

测试通过。

刚才仅仅分析了,我们之前路径的问题所在,还有一点我想也是大家关心的,就是通配符是怎么匹配的呢?那我们就继续分析源码,回到 findPathMatchingResources方法。

将路径分成包含通配符和不包含的两部分后,Spring会将根路径生成一个Resource,用的还是getResources方法。然后检查根路径的类型,是否是Jar路径?是否是VFS路径?对于我们这种普通路径,自然走到最后的分支。

主要的匹配工作,是从doRetrieveMatchingFiles方法开始的。前面的都是简单的封装过渡,在retrieveMatchingFiles中判断了下根路径是否存在、是否是文件夹、是否可读。否则都直接返回空集合。都满足了以后才进入,doRetrieveMatchingFiles方法。在该方法中,

首先,列出该文件夹下的所有文件。

然后,遍历所有文件,如果仍是文件夹,递归调用doRetrieveMatchingFiles方法。如果不是,则调用getPathMatcher().match(fullPattern, currPath)进行文件名的最后匹配,将满足条件放入结果集。

该match方法,实际是调用了AntPathMatcher的doMatch方法,

比较方法如下,

首先,分别将输入路径和待比较路径,按照文件分隔符分割成字符串数组。(例如:{”D:“, "workspace-home", "spring-custom"…})

然后,设置好起始和结束位后,对这两个数组进行while循环(代码中第一个while循环),逐断比较匹配(matchStrings)情况。如果有一段不满足则返回fasle。

由于我们当前的测试路径中不包含**的部分,所以主要的判断基本都在第一个while就可以搞定。这部分工作自然是由matchStrings完成的。

试想一下:如果让你完成一个通配符路径匹配的功能,你会如何去做?是否自然的联想到了正则?似乎是个好选择,看看spring是怎么做的。

在构造AntPathStringMatcher实例的时候,spring果然也创建了正则:

简单说,就是spring先用正则:

找到路径中的"?"和"*"通配符,然后转换为Java正则的任意字符"."和".*"。生成另一个正则表达式去匹配查找到的文件的路径。如果匹配则返回true。

至此,对于路径中包含?和*的情况解析spring的解析方式,我们已经基本了解了。本来想把**的情况一起介绍了,不过考虑的篇幅过长,我们下次再一起研究吧。

写在最后:所有研究均为笔者工作之余消遣之做,香港服务器租用,错误指出还望指出,欢迎各种形式和内容的探讨。

博主推荐:

Java Coder技术交流高级群:91513074

推荐文章:

最普通IT男-苦逼coder杂谈

本文出自 “苦逼coder” 博客,谢绝转载!

找寻隐藏在山间的纯净和那“鸟鸣山更幽”的飞鸟。

Spring源码学习-含有通配符路径解析(上)

相关文章:

你感兴趣的文章:

标签云: