Différence de préfixe Spring classpath

141

Documenté ici, il déclare

Ce préfixe spécial spécifie que toutes les ressources classpath qui correspondent au nom donné doivent être obtenues (en interne, cela se produit essentiellement via un appel ClassLoader.getResources (...)), puis fusionnées pour former la définition finale du contexte d'application.

Quelqu'un peut-il expliquer cela?

Quelle est la différence entre utiliser classpath*:conf/appContext.xmlplutôt que classpath:conf/appContext.xmlsans astérisque.

JavaRocky
la source
Les futurs lecteurs, voient également ce bug, avec un "statut = refusé". github.com/spring-projects/spring-framework/issues/16017 Juste au cas où l'URL échouerait, le titre du message de bogue est "Importation d'un fichier XML à partir de la racine d'un fichier JAR avec chemin de classe générique et chemin générique ne fonctionne pas [SPR-11390] "
granadaCoder

Réponses:

207

DÉFINITION SIMPLE

Le classpath*:conf/appContext.xmlsignifie simplement que tous les fichiers appContext.xml sousconf dossiers dans tous vos pots sur le chemin de classe seront ramassés et réunis dans un grand contexte d'application.

En revanche, classpath:conf/appContext.xmlne chargera qu'un de ces fichiers ... le premier trouvé sur votre chemin de classe.

Eugene Ryzhikov
la source
6
il y a une autre différence intéressante entre eux. Voir aussi ma question: stackoverflow.com/questions/16985770/…
Eugene
27
Une chose très importante - si vous utilisez le * et que Spring ne trouve aucune correspondance, il ne se plaindra pas. Si vous n'utilisez pas le * et qu'il n'y a pas de correspondance, le contexte ne démarrera pas (!)
Roy Truelove
39

La classpath*:...syntaxe est principalement utile lorsque vous souhaitez créer un contexte d'application à partir de plusieurs fichiers de définition de bean, en utilisant une syntaxe générique.

Par exemple, si vous construisez votre contexte en utilisant classpath*:appContext.xml, le chemin de classe sera analysé pour chaque ressource appeléeappContext.xml dans le chemin de classe, et les définitions de bean de toutes fusionnées dans un seul contexte.

En revanche, classpath:conf/appContext.xmlobtiendra un et un seul fichier appelé à appContext.xmlpartir du chemin de classe. S'il y en a plus d'un, les autres seront ignorés.

skaffman
la source
2
Le classpath * cherchera-t-il également dans les sous-répertoires? En d'autres termes, si j'ai appContext.xml dans la racine du chemin de classe et un dans /dir/appContext.xml, sera-t-il chargé à la fois lorsque j'utilise le chemin de classe *: appContext.xml?
AHungerArtist
21

classpath *: il fait référence à une liste de ressources et charge tous ces fichiers présents dans le chemin de classe et la liste peut être vide et si aucun fichier de ce type n'est présent dans le chemin de classe, l'application ne lève aucune exception (ignore simplement l'erreur).

classpath: il fait référence à une certaine ressource et charge uniquement le premier fichier trouvé sur le classpath et si aucun fichier de ce type n'est présent dans le classpath, il lèvera une exception

java.io.FileNotFoundException: class path resource [conf/appContext.xml] cannot be opened because it does not exist
Les bactéries
la source
Document officiel "Il n'est pas possible d'utiliser le préfixe classpath *: pour construire un réel Resource, car une ressource pointe vers une seule ressource à la fois." en plus je viens de recevoir cette erreur bizarre, c'est comme ça que je me suis retrouvé ici. Si vous prévoyez d'importer des ressources, l'utilisation du préfixe de chemin de classe générique n'a aucun sens.
GabrielOshiro
0

Le code source 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
la source
Pouvez-vous expliquer?
RtmY