if (content.isDirectory() && getPathMatcher().matchStart(fullPattern, currPath + "/")) {
doRetrieveMatchingFiles(fullPattern, content, result);
}
if (getPathMatcher().match(fullPattern, currPath)) {
result.add(content);
}
}
}
最后,需要注意的是,由于ClassLoader.getResources()方法存在的限制,当传入一个空字符串时,它只能从classpath的文件目录下查找,而不会从Jar文件的根目录下查找,因而对”classpath*:”前缀的资源来说,找不到Jar根路径下的资源。即如果我们有以下定义:”classpath*:*.xml”,如果只有在Jar文件的根目录下存在*.xml文件,那么这个pattern将返回空的Resource数组。解决方法是不要再Jar文件根目录中放文件,可以将这些文件放到Jar文件中的resources、config等目录下去。并且也不要在”classpath*:”之后加一些通配符,如”classpath*:**/*Enum.class”,至少在”classpath*:”后加入一个不存在通配符的路径名。
ServletContextResourcePatternResolver类
ServletContextResourcePatternResolver类继承自PathMatchingResourcePatternResolver类,它重写了父类的文件查找逻辑,即对ServletContextResource资源使用ServletContext.getResourcePaths()方法来查找参数目录下的文件,而不是File.listFiles()方法:
protected Set doFindPathMatchingFileResources(Resource rootDirResource, String subPattern) throws IOException {
if (rootDirResource instanceof ServletContextResource) {
ServletContextResource scResource = (ServletContextResource) rootDirResource;
ServletContext sc = scResource.getServletContext();
String fullPattern = scResource.getPath() + subPattern;
Set result = new LinkedHashSet(8);
doRetrieveMatchingServletContextResources(sc, fullPattern, scResource.getPath(), result);
return result;
}
else {
return super.doFindPathMatchingFileResources(rootDirResource, subPattern);
}
}
AbstractApplicationContext对ResourcePatternResolver接口的实现
在AbstractApplicationContext中,对ResourcePatternResolver的实现只是简单的将getResources()方法的实现代理给resourcePatternResolver字段,而该字段默认在AbstractApplicationContext创建时新建一个PathMatchingResourcePatternResolver实例:
public AbstractApplicationContext(ApplicationContext parent) {
this.parent = parent;
this.resourcePatternResolver = getResourcePatternResolver();
}
protected ResourcePatternResolver getResourcePatternResolver() {
return new PathMatchingResourcePatternResolver(this);
}
public Resource[] getResources(String locationPattern) throws IOException {
return this.resourcePatternResolver.getResources(locationPattern);
}