Unterschied im Spring-Klassenpfad-Präfix


140

Dokumentierte hier heißt es

Dieses spezielle Präfix gibt an, dass alle Klassenpfadressourcen, die dem angegebenen Namen entsprechen, abgerufen werden müssen (intern geschieht dies im Wesentlichen über einen Aufruf von ClassLoader.getResources (...)) und dann zusammengeführt werden, um die endgültige Anwendungskontextdefinition zu bilden.

Kann das jemand erklären?

Was ist der Unterschied zwischen der Verwendung classpath*:conf/appContext.xmlund der Verwendung classpath:conf/appContext.xmlohne Sternchen ?


Zukünftige Leser sehen diesen Fehler ebenfalls mit einem "Status = abgelehnt". github.com/spring-projects/spring-framework/issues/16017 Für den Fall, dass die URL irgendwann einmal ausfällt, lautet der Titel des Fehlerpostens "Import einer XML-Datei aus dem Stammverzeichnis einer JAR-Datei mit Platzhalterklassenpfad und Platzhalterpfad funktioniert nicht [SPR-11390] "
granadaCoder

Antworten:


206

EINFACHE DEFINITION

Das classpath*:conf/appContext.xmlbedeutet einfach, dass alle appContext.xml-Dateien unter confOrdnern in all Ihren Gläsern im Klassenpfad aufgenommen und zu einem großen Anwendungskontext zusammengefügt werden.

Im Gegensatz dazu classpath:conf/appContext.xmlwird nur eine solche Datei geladen ... die erste, die in Ihrem Klassenpfad gefunden wurde.


6
Es gibt noch einen interessanten Unterschied zwischen ihnen. Siehe meine Frage auch: stackoverflow.com/questions/16985770/…
Eugene

27
Eine sehr wichtige Sache - wenn Sie das * verwenden und Spring keine Übereinstimmungen findet, wird es sich nicht beschweren. Wenn Sie das * nicht verwenden und es keine Übereinstimmungen gibt, wird der Kontext nicht gestartet (!)
Roy Truelove

39

Die classpath*:...Syntax ist vor allem dann nützlich, wenn Sie einen Anwendungskontext mithilfe der Platzhaltersyntax aus mehreren Bean-Definitionsdateien erstellen möchten.

Wenn Sie beispielsweise Ihren Kontext mit classpath*:appContext.xmlerstellen, wird der Klassenpfad nach jeder appContext.xmlim Klassenpfad aufgerufenen Ressource durchsucht und die Bean-Definitionen von allen in einem einzigen Kontext zusammengeführt.

Im Gegensatz classpath:conf/appContext.xmldazu erhalten Sie eine und nur eine Datei, appContext.xmldie vom Klassenpfad aufgerufen wird . Wenn es mehr als eine gibt, werden die anderen ignoriert.


2
Wird classpath * auch in Unterverzeichnissen angezeigt? Mit anderen Worten, wenn ich appContext.xml im Stamm des Klassenpfads und eine in /dir/appContext.xml habe, werden beide geladen, wenn ich classpath *: appContext.xml verwende?
AHungerArtist

21

Klassenpfad *: Es bezieht sich auf eine Liste von Ressourcen und lädt alle im Klassenpfad vorhandenen Dateien. Die Liste kann leer sein. Wenn im Klassenpfad keine solche Datei vorhanden ist, löst die Anwendung keine Ausnahme aus (ignoriert nur den Fehler).

Klassenpfad: Er bezieht sich auf eine bestimmte Ressource und lädt nur die erste im Klassenpfad gefundene Datei. Wenn im Klassenpfad keine solche Datei vorhanden ist, wird eine Ausnahme ausgelöst

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

Offizielles Dokument "Es ist nicht möglich, das Präfix classpath *: zu verwenden, um eine tatsächliche ResourceRessource zu erstellen , da eine Ressource jeweils nur auf eine Ressource verweist." Außerdem habe ich gerade diesen seltsamen Fehler bekommen, so bin ich hier gelandet. Wenn Sie Ressourcen importieren möchten, ist es nicht sinnvoll, das Platzhalter-Klassenpfadpräfix zu verwenden.
GabrielOshiro

0

Der Quellcode von 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)};
      }
   }
}  

Kannst du bitte Erklären?
RtmY
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.