Różnica przedrostków ścieżki klas wiosennych


141

Udokumentowane tutaj stwierdza

Ten specjalny przedrostek określa, że ​​wszystkie zasoby ścieżki klas, które pasują do podanej nazwy, muszą zostać uzyskane (wewnętrznie, zasadniczo dzieje się to za pośrednictwem wywołania ClassLoader.getResources (...)), a następnie scalone w celu utworzenia ostatecznej definicji kontekstu aplikacji.

Czy ktoś może to wyjaśnić?

Jaka jest różnica między używaniem classpath*:conf/appContext.xmla classpath:conf/appContext.xmlbez gwiazdki.


Przyszli czytelnicy również zobaczą ten błąd ze stanem = odrzucony. github.com/spring-projects/spring-framework/issues/16017 Na wypadek, gdyby adres URL w końcu zawiódł , tytuł posta o błędzie brzmi „Import pliku XML z katalogu głównego pliku JAR ze ścieżką klas i ścieżką symboli wieloznacznych nie działa [SPR-11390] ”
granadaCoder,

Odpowiedzi:


207

PROSTA DEFINICJA

classpath*:conf/appContext.xmlOznacza po prostu, że wszystkie pliki appContext.xml pod conffoldery we wszystkich swoich słoików na ścieżce klasy zostanie odebrany i połączone w jeden duży kontekście aplikacji.

Natomiast classpath:conf/appContext.xmlzaładuje tylko jeden taki plik ... pierwszy znaleziony w ścieżce klas.


6
jest między nimi jeszcze jedna interesująca różnica. Zobacz także moje pytanie: stackoverflow.com/questions/16985770/…
Eugene

27
Jedna bardzo ważna rzecz - jeśli użyjesz * i Spring nie znajdzie żadnych dopasowań, nie będzie narzekać. Jeśli nie użyjesz * i nie ma żadnych dopasowań, kontekst się nie uruchomi (!)
Roy Truelove

39

classpath*:...Składnia jest przydatna przede wszystkim, gdy chcemy zbudować kontekst aplikacji z wielu plików definicji fasoli, używając składni wieloznaczny.

Na przykład, jeśli konstruujesz swój kontekst przy użyciu classpath*:appContext.xml, ścieżka klas zostanie przeskanowana pod kątem każdego zasobu wywoływanego appContext.xmlw ścieżce klas, a definicje fasoli z nich wszystkich zostaną połączone w jeden kontekst.

W przeciwieństwie do classpath:conf/appContext.xmltego uzyska jeden i tylko jeden plik wywołany appContext.xmlze ścieżki klas. Jeśli jest więcej niż jeden, pozostałe zostaną zignorowane.


2
Czy ścieżka klasy * będzie również wyglądać w podkatalogach? Innymi słowy, czy jeśli mam appContext.xml w katalogu głównym ścieżki klas i jedną w /dir/appContext.xml, czy załaduje się oba, gdy użyję ścieżki classpath *: appContext.xml?
AHungerArtist

21

classpath *: Odnosi się do listy zasobów i ładuje wszystkie takie pliki obecne w ścieżce klas, a lista może być pusta, a jeśli takiego pliku nie ma w ścieżce klasy, aplikacja nie zgłasza żadnego wyjątku (po prostu ignoruje błąd).

classpath: Odnosi się do określonego zasobu i ładuje tylko pierwszy plik znaleziony na ścieżce klas, a jeśli takiego pliku nie ma w ścieżce klas, zgłosi wyjątek

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

Official Doc "Nie można użyć prefiksu classpath *: do skonstruowania rzeczywistego Resource, ponieważ zasób wskazuje tylko jeden zasób na raz." plus właśnie dostałem ten dziwny błąd, tak oto znalazłem się tutaj. Jeśli zamierzasz zaimportować zasób, nie ma sensu używać przedrostka ścieżki klas z symbolem wieloznacznym.
GabrielOshiro

0

Kod źródłowy Springa:

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)};
      }
   }
}  

Czy możesz wyjaśnić?
RtmY
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.