该文章由https://blog.youkuaiyun.com/arjelarxfc/article/details/78223983提供思路。
网上很多人都说classpath 和 classpath* 的区别:
classpath:只会到你指定的class路径中查找文件;
classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找.
那我们现在研究一下,下面是spring加载文件的源码:
public Resource[] getResources(String locationPattern) throws IOException {
Assert.notNull(locationPattern, "Location pattern must not be null");
//是否以classpath*开头
if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {
//是否包含?或者*
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)};
}
}
}
protected Resource[] findAllClassPathResources(String location) throws IOException {
String path = location;
if (path.startsWith("/")) {
path = path.substring(1);
}
Enumeration resourceUrls = getClassLoader().getResources(path);
Set<Resource> result = new LinkedHashSet<Resource>(16);
while (resourceUrls.hasMoreElements()) {
URL url = (URL) resourceUrls.nextElement();
result.add(convertClassLoaderURL(url));
}
return result.toArray(new Resource[result.size()]);
}
分析总结如下:
1.无论是classpath还是classpath*都可以加载整个classpath下(包括jar包里面)的资源文件。
2.classpath只会返回第一个匹配的资源,查找路径是优先在项目中存在资源文件,再查找jar包。
有次在idea中使用时,出现问题。还原问题:在web.xml配置
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml
</param-value>
</context-param>
时,用的是classpath*:applicationContext.xml,总是报错,无法加载bean。后来改为classpath:applicationContext.xml程序成功启动。当时一直不明白其中缘由,因为程序在eclipse中是可以正常启动的。