Spring类路径前缀差异


141

记录在这里它说

这个特殊的前缀指定必须获取与给定名称匹配的所有类路径资源(内部,这实际上是通过ClassLoader.getResources(...)调用发生的),然后合并以形成最终的应用程序上下文定义。

有人可以解释吗?

使用classpath*:conf/appContext.xmlclasspath:conf/appContext.xml不使用星号有什么区别?


将来的读者也会看到此错误,并带有“ status = declined”。 github.com/spring-projects/spring-framework/issues/16017 以防万一URL最终失败,该错误文章的标题是“从具有通配符类路径和通配符路径的JAR文件的根目录导入XML文件不起作用[SPR-
11390

Answers:


207

简单的定义

classpath*:conf/appContext.xml只是意味着,将拾取类路径上所有jar中文件conf夹下的所有appContext.xml文件,并将其加入一个大的应用程序上下文中。

相反,classpath:conf/appContext.xml加载一个这样的文件 ...在类路径中找到的第一个文件


6
它们之间还有一个有趣的区别。另请参阅我的问题:stackoverflow.com/questions/16985770/…–
尤金

27
一件非常重要的事情-如果使用*,而Spring没有找到匹配项,它将不会抱怨。如果您不使用*并且没有匹配项,则上下文将不会启动(!)
Roy Truelove

39

classpath*:...语法主要在您希望使用通配符语法从多个bean定义文件构建应用程序上下文时有用。

例如,如果您使用构造上下文classpath*:appContext.xml,则将扫描类路径以查找称为appContext.xml在类路径中,并将所有这些中的bean定义合并到一个上下文中。

相反,classpath:conf/appContext.xml将从appContext.xml类路径中获得一个且只有一个文件。如果不止一个,则其他将被忽略。


2
classpath *也会在子目录中查找吗?换句话说,如果我在类路径根目录中有appContext.xml,在/dir/appContext.xml中有一个,那么当我使用classpath *:appContext.xml时,是否会同时加载?
AHungerArtist

21

classpath *: 引用资源列表,加载类路径中存在的所有此类文件,并且列表可以为空,并且如果类路径中不存在此类文件,则应用程序不会引发任何异常(只是忽略错误)。

classpath:它引用某种资源,并且仅加载在类路径上找到的第一个文件,如果在类路径中不存在此类文件,它将抛出异常

java.io.FileNotFoundException: class path resource [conf/appContext.xml] cannot be opened because it does not exist

官方文档 “无法使用classpath *:前缀构造一个real Resource,因为资源一次仅指向一个资源。” 再加上我刚得到这个奇怪的错误,那就是我到这里结束的方式。如果要导入资源,则使用通配符classpath前缀是没有意义的。
加布里埃尔·奥西罗(GabrielOshiro)

0

Spring的源代码:

public Resource[] getResources(String locationPattern) throws IOException {
   Assert.notNull(locationPattern, "Location pattern must not be null");
   //CLASSPATH_ALL_URL_PREFIX="classpath*:"
   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)};
      }
   }
}  

你能解释一下吗?
RtmY
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.