Diferença de prefixo do caminho de classe do Spring


141

Documentado aqui afirma

Esse prefixo especial especifica que todos os recursos do caminho de classe que correspondem ao nome especificado devem ser obtidos (internamente, isso ocorre basicamente por meio de uma chamada ClassLoader.getResources (...)) e depois mesclados para formar a definição final do contexto do aplicativo.

Alguém pode explicar isso?

Qual é a diferença entre usar classpath*:conf/appContext.xmlem oposição a classpath:conf/appContext.xmlsem o asterisco.


Os futuros leitores também veem esse bug, com um "status = recusado". github.com/spring-projects/spring-framework/issues/16017 Caso a URL eventualmente falhe, o título da publicação do erro é "Importação de um arquivo XML da raiz de um arquivo JAR com caminho de classe curinga e caminho curinga não funciona [SPR-11390] "
granadaCoder 24/02/19

Respostas:


207

DEFINIÇÃO SIMPLES

O classpath*:conf/appContext.xmlsimplesmente significa que todos os arquivos appContext.xml sob confpastas em todos os seus frascos no classpath será pego e juntou-se em um contexto de aplicação grande.

Por outro lado, classpath:conf/appContext.xmlcarregará apenas um desses arquivos ... o primeiro encontrado no seu caminho de classe.


6
há mais uma diferença interessante entre eles. Veja minha pergunta também: stackoverflow.com/questions/16985770/…
Eugene

27
Uma coisa muito importante - se você usar o * e o Spring não encontrar correspondências, ele não irá reclamar. Se você não usar o * e não há jogos, o contexto não arranca (!)
Roy Truelove

39

A classpath*:...sintaxe é útil principalmente quando você deseja criar um contexto de aplicativo a partir de vários arquivos de definição de bean, usando a sintaxe curinga.

Por exemplo, se você construir seu contexto usando classpath*:appContext.xml, o caminho de classe será verificado para todos os recursos chamados appContext.xmlno caminho de classe e as definições de bean de todos eles serão mescladas em um único contexto.

Por outro lado, classpath:conf/appContext.xmlobterá um e apenas um arquivo chamado appContext.xmlno caminho de classe. Se houver mais de um, os outros serão ignorados.


2
O caminho da classe * também aparecerá nos subdiretórios? Em outras palavras, se eu tiver appContext.xml na raiz do caminho de classe e um em /dir/appContext.xml, ele carregará os dois quando eu usar o caminho de classe *: appContext.xml?
AHungerArtist 22/09

21

caminho de classe *: refere-se a uma lista de recursos e carrega todos os arquivos presentes no caminho de classe e a lista pode estar vazia e, se nenhum arquivo estiver presente no caminho de classe, o aplicativo não lança nenhuma exceção (apenas ignora o erro).

caminho de classe: refere-se a um determinado recurso e carrega apenas o primeiro arquivo encontrado no caminho de classe e, se esse arquivo não estiver presente no caminho de classe, gerará uma exceção

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

Documento oficial "Não é possível usar o prefixo classpath *: para construir um real Resource, pois um recurso aponta para apenas um recurso por vez." além disso, acabei de receber esse erro estranho, foi assim que acabei aqui. Se você for importar recursos, não faz sentido usar o prefixo do caminho de classe curinga.
GabrielOshiro 25/09

0

O código fonte do 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)};
      }
   }
}  

Você pode explicar, por favor?
RtmY
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.