在spring的配置文件中、经常看见类似这样的配置路径:
Java代码
classpath:/com/module/**/*sql.xml
系统会根据配置路径自动加载符合路径规则的xml文件
假如让你实现这样的功能:
根据一个通配符路径加载符合规则的xml文件你会怎么做?
先看一个小例子:
Java代码
import java.io.IOException;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
public class XMLManager {
private String location = "classpath:*.xml";
public void readFile() throws IOException {
ResourcePatternResolver resourceLoader = new PathMatchingResourcePatternResolver();
Resource[] source = resourceLoader.getResources(location);
for (int i = 0; i < source.length; i++) {
Resource resource = source[i];
System.out.println(resource.getFilename());
}
}
public static void main(String[] args) {
XMLManager m = new XMLManager();
try {
m.readFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
输出结果:
Java代码
applicationContext.xml
logback.xml
menu_my.xml
是不是很简单?
只要调用PathMatchingResourcePatternResolver的getResources方法就可以实现我们想要的功能。
下面深入研究一下spring的源码PathMatchingResourcePatternResolver:
1、getResources方法
Java代码
public Resource[] getResources(String locationPattern) throws IOException {
Assert.notNull(locationPattern, "Location pattern must not be null");
if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {
// a class path resource (multiple resources for same name possible)
if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {
// a class path resource pattern
return findPathMatchingResources(locationPattern);
}
else {
// all class path resources with the given name
return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));
}
}
else {
// Only look for a pattern after a prefix here
// (to not get fooled by a pattern symbol in a strange prefix).
int prefixEnd = locationPattern.indexOf(":") + 1;
if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) {
// a file pattern
return findPathMatchingResources(locationPattern);
}
else {
// a single resource with the given name
return new Resource[] {getResourceLoader().getResource(locationPattern)};
}
}
}
该方法主要是判断locationPattern是否包含有通配符、如果包含通配符则调用findPathMatchingResources方法、没有包含通配符就不需要解析了
2、findPathMatchingResources方法
Java代码
protected Resource[] findPathMatchingResources(String locationPattern) throws IOException {
String rootDirPath = determineRootDir(locationPattern);
String subPattern = locationPattern.substring(rootDirPath.length());
Resource[] rootDirResources = getResources(rootDirPath);
Set
for (Resource rootDirResource : rootDirResources) {
rootDirResource = resolveRootDirResource(rootDirResource);
if (isJarResource(rootDirResource)) {