Diferencia de prefijo de classpath de primavera

141

Documentado aquí dice

Este prefijo especial especifica que se deben obtener todos los recursos de classpath que coinciden con el nombre dado (internamente, esto sucede esencialmente a través de una llamada ClassLoader.getResources (...)), y luego se fusionan para formar la definición final del contexto de la aplicación.

¿Alguien puede explicar esto?

¿Cuál es la diferencia entre usar classpath*:conf/appContext.xmlen lugar de classpath:conf/appContext.xmlsin el asterisco?

JavaRocky
fuente
Los futuros lectores también ven este error, con un "estado = rechazado". github.com/spring-projects/spring-framework/issues/16017 En caso de que la URL falle, el título de la publicación del error es "Importar un archivo XML desde la raíz de un archivo JAR con ruta de acceso comodín y ruta de acceso comodín no funciona [SPR-11390] "
granadaCoder

Respuestas:

207

DEFINICIÓN SIMPLE

El classpath*:conf/appContext.xmlsimplemente significa que todos los archivos appContext.xml bajo confcarpetas en todos sus frascos en la ruta de clase serán recogidos y se unieron en un solo contexto de aplicación grande.

Por el contrario, classpath:conf/appContext.xmlcargará solo uno de esos archivos ... el primero encontrado en su classpath.

Eugene Ryzhikov
fuente
66
Hay una diferencia más interesante entre ellos. Vea también mi pregunta: stackoverflow.com/questions/16985770/…
Eugene
27
Una cosa muy importante: si usa * y Spring no encuentra coincidencias, no se quejará. Si no usa el * y no hay coincidencias, el contexto no se iniciará (!)
Roy Truelove
39

La classpath*:...sintaxis es útil principalmente cuando desea crear un contexto de aplicación a partir de múltiples archivos de definición de bean, utilizando la sintaxis comodín.

Por ejemplo, si construye su contexto utilizando classpath*:appContext.xml, el classpath será escaneado para cada recurso llamado appContext.xmlen el classpath, y las definiciones de bean de todos ellos se fusionaron en un solo contexto.

Por el contrario, classpath:conf/appContext.xmlobtendrá uno y solo un archivo llamado appContext.xmldesde el classpath. Si hay más de uno, los demás serán ignorados.

skaffman
fuente
2
¿Classpath * también se verá en subdirectorios? En otras palabras, si tengo appContext.xml en la raíz de classpath y uno en /dir/appContext.xml, ¿cargará ambos cuando use classpath *: appContext.xml?
AHungerArtist
21

classpath *: se refiere a una lista de recursos y carga todos los archivos presentes en el classpath y la lista puede estar vacía y si no hay ningún archivo presente en el classpath, la aplicación no arroja ninguna excepción (simplemente ignora el error).

classpath: se refiere a un determinado recurso y carga solo el primer archivo encontrado en el classpath y, si no hay ningún archivo en el classpath, arrojará una excepción

java.io.FileNotFoundException: class path resource [conf/appContext.xml] cannot be opened because it does not exist
Las bacterias
fuente
Doc oficial "No es posible usar el classpath *: prefijo para construir un real Resource, ya que un recurso apunta a un solo recurso a la vez". Además, acabo de recibir este extraño error, así es como terminé aquí. Si va a importar recursos, entonces no tiene sentido usar el prefijo comodín classpath.
GabrielOshiro
0

El código fuente de 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)};
      }
   }
}  
zzz
fuente
¿Puede usted explicar por favor?
RtmY