Class PathMatchingResourcePatternResolver
- All Implemented Interfaces:
ResourceLoader
,ResourcePatternResolver
- Direct Known Subclasses:
ServletContextResourcePatternResolver
ResourcePatternResolver
implementation that is able to resolve a
specified resource location path into one or more matching Resources.
The source path may be a simple path which has a one-to-one mapping to a
target Resource
, or alternatively may
contain the special "classpath*:
" prefix and/or internal Ant-style
path patterns (matched using Spring's AntPathMatcher
utility). Both
of the latter are effectively wildcards.
No Wildcards
In the simple case, if the specified location path does not start with the
"classpath*:
" prefix and does not contain a PathMatcher
pattern, this resolver will simply return a single resource via a
getResource()
call on the underlying ResourceLoader
.
Examples are real URLs such as "file:C:/context.xml
", pseudo-URLs
such as "classpath:/context.xml
", and simple unprefixed paths
such as "/WEB-INF/context.xml
". The latter will resolve in a
fashion specific to the underlying ResourceLoader
(e.g.
ServletContextResource
for a WebApplicationContext
).
Ant-style Patterns
When the path location contains an Ant-style pattern, for example:
/WEB-INF/*-context.xml com/example/**/applicationContext.xml file:C:/some/path/*-context.xml classpath:com/example/**/applicationContext.xmlthe resolver follows a more complex but defined procedure to try to resolve the wildcard. It produces a
Resource
for the path up to the last
non-wildcard segment and obtains a URL
from it. If this URL is not a
"jar:
" URL or container-specific variant (e.g. "zip:
" in WebLogic,
"wsjar
" in WebSphere", etc.), then the root directory of the filesystem
associated with the URL is obtained and used to resolve the wildcards by walking
the filesystem. In the case of a jar URL, the resolver either gets a
java.net.JarURLConnection
from it, or manually parses the jar URL, and
then traverses the contents of the jar file, to resolve the wildcards.
Implications on Portability
If the specified path is already a file URL (either explicitly, or
implicitly because the base ResourceLoader
is a filesystem one),
then wildcarding is guaranteed to work in a completely portable fashion.
If the specified path is a class path location, then the resolver must
obtain the last non-wildcard path segment URL via a
Classloader.getResource()
call. Since this is just a
node of the path (not the file at the end) it is actually undefined
(in the ClassLoader Javadocs) exactly what sort of URL is returned in
this case. In practice, it is usually a java.io.File
representing
the directory, where the class path resource resolves to a filesystem
location, or a jar URL of some sort, where the class path resource resolves
to a jar location. Still, there is a portability concern on this operation.
If a jar URL is obtained for the last non-wildcard segment, the resolver
must be able to get a java.net.JarURLConnection
from it, or
manually parse the jar URL, to be able to walk the contents of the jar
and resolve the wildcard. This will work in most environments but will
fail in others, and it is strongly recommended that the wildcard
resolution of resources coming from jars be thoroughly tested in your
specific environment before you rely on it.
classpath*:
Prefix
There is special support for retrieving multiple class path resources with
the same name, via the "classpath*:
" prefix. For example,
"classpath*:META-INF/beans.xml
" will find all "META-INF/beans.xml"
files in the class path, be it in "classes" directories or in JAR files.
This is particularly useful for autodetecting config files of the same name
at the same location within each jar file. Internally, this happens via a
ClassLoader.getResources()
call, and is completely portable.
The "classpath*:
" prefix can also be combined with a PathMatcher
pattern in the rest of the location path — for example,
"classpath*:META-INF/*-beans.xml"
. In this case, the resolution strategy
is fairly simple: a ClassLoader.getResources()
call is used on the last
non-wildcard path segment to get all the matching resources in the class loader
hierarchy, and then off each resource the same PathMatcher
resolution
strategy described above is used for the wildcard sub pattern.
Other Notes
As of Spring Framework 6.0, if getResources(String)
is invoked with
a location pattern using the "classpath*:
" prefix it will first search
all modules in the boot layer, excluding
system modules. It will then search the
class path using ClassLoader
APIs as described previously and return the
combined results. Consequently, some of the limitations of class path searches
may not apply when applications are deployed as modules.
WARNING: Note that "classpath*:
" when combined with
Ant-style patterns will only work reliably with at least one root directory
before the pattern starts, unless the actual target files reside in the file
system. This means that a pattern like "classpath*:*.xml
" will
not retrieve files from the root of jar files but rather only from the
root of expanded directories. This originates from a limitation in the JDK's
ClassLoader.getResources()
method which only returns file system
locations for a passed-in empty String (indicating potential roots to search).
This ResourcePatternResolver
implementation tries to mitigate the
jar root lookup limitation through URLClassLoader
introspection and
"java.class.path
" manifest evaluation; however, without portability
guarantees.
WARNING: Ant-style patterns with "classpath:
" resources are not
guaranteed to find matching resources if the base package to search is available
in multiple class path locations. This is because a resource such as
com/example/package1/service-context.xmlmay exist in only one class path location, but when a location pattern such as
classpath:com/example/**/service-context.xmlis used to try to resolve it, the resolver will work off the (first) URL returned by
getResource("com/example")
. If the com/example
base
package node exists in multiple class path locations, the actual desired resource
may not be present under the com/example
base package in the first URL.
Therefore, preferably, use "classpath*:
" with the same Ant-style pattern
in such a case, which will search all class path locations that contain
the base package.- Since:
- 1.0.2
- Author:
- Juergen Hoeller, Colin Sampaleanu, Marius Bogoevici, Costin Leau, Phillip Webb, Sam Brannen, Sebastien Deleuze, Dave Syer
- See Also:
-
Field Summary
Fields inherited from interface org.springframework.core.io.ResourceLoader
CLASSPATH_URL_PREFIX
Fields inherited from interface org.springframework.core.io.support.ResourcePatternResolver
CLASSPATH_ALL_URL_PREFIX
-
Constructor Summary
ConstructorDescriptionCreate aPathMatchingResourcePatternResolver
with aDefaultResourceLoader
.PathMatchingResourcePatternResolver
(ClassLoader classLoader) Create aPathMatchingResourcePatternResolver
with aDefaultResourceLoader
and the suppliedClassLoader
.PathMatchingResourcePatternResolver
(ResourceLoader resourceLoader) Create aPathMatchingResourcePatternResolver
with the suppliedResourceLoader
. -
Method Summary
Modifier and TypeMethodDescriptionprotected void
addAllClassLoaderJarRoots
(ClassLoader classLoader, Set<Resource> result) Search allURLClassLoader
URLs for jar file references and add each to the given set of resources in the form of a pointer to the root of the jar file content.protected void
addClassPathManifestEntries
(Set<Resource> result) Determine jar file references fromClass-Path
manifest entries (which are added to thejava.class.path
JVM system property by the system class loader) and add each to the given set of resources in the form of a pointer to the root of the jar file content.protected Resource
convertClassLoaderURL
(URL url) Convert the given URL as returned from the configuredClassLoader
into aResource
, applying to path lookups without a pattern (seefindAllClassPathResources(java.lang.String)
).protected String
determineRootDir
(String location) Determine the root directory for the given location.Find all class path resources with the given path via the configuredClassLoader
.doFindPathMatchingFileResources
(Resource rootDirResource, String subPattern) Find all resources in the file system of the supplied root directory that match the given location sub pattern via the Ant-stylePathMatcher
.doFindPathMatchingJarResources
(Resource rootDirResource, URL rootDirUrl, String subPattern) Find all resources in jar files that match the given location pattern via the Ant-stylePathMatcher
.protected Resource[]
findAllClassPathResources
(String location) Find all class location resources with the given location via the ClassLoader.findAllModulePathResources
(String locationPattern) Resolve the given location pattern intoResource
objects for all matching resources found in the module path.protected Resource[]
findPathMatchingResources
(String locationPattern) Find all resources that match the given location pattern via the Ant-stylePathMatcher
.Expose theClassLoader
used by thisResourceLoader
.protected JarFile
getJarFile
(String jarFileUrl) Resolve the given jar file URL into a JarFile object.Return thePathMatcher
that this resource pattern resolver uses.getResource
(String location) Return aResource
handle for the specified resource location.Return theResourceLoader
that this pattern resolver works with.Resource[]
getResources
(String locationPattern) Resolve the given location pattern intoResource
objects.protected boolean
isJarResource
(Resource resource) Determine if the given resource handle indicates a jar resource that thedoFindPathMatchingJarResources(org.springframework.core.io.Resource, java.net.URL, java.lang.String)
method can handle.protected Resource
resolveRootDirResource
(Resource original) Resolve the supplied root directory resource for path matching.void
setPathMatcher
(PathMatcher pathMatcher) Set thePathMatcher
implementation to use for this resource pattern resolver.
-
Constructor Details
-
PathMatchingResourcePatternResolver
public PathMatchingResourcePatternResolver()Create aPathMatchingResourcePatternResolver
with aDefaultResourceLoader
.ClassLoader access will happen via the thread context class loader.
- See Also:
-
PathMatchingResourcePatternResolver
Create aPathMatchingResourcePatternResolver
with the suppliedResourceLoader
.ClassLoader access will happen via the thread context class loader.
- Parameters:
resourceLoader
- theResourceLoader
to load root directories and actual resources with
-
PathMatchingResourcePatternResolver
Create aPathMatchingResourcePatternResolver
with aDefaultResourceLoader
and the suppliedClassLoader
.- Parameters:
classLoader
- the ClassLoader to load class path resources with, ornull
for using the thread context class loader at the time of actual resource access- See Also:
-
-
Method Details
-
getResourceLoader
Return theResourceLoader
that this pattern resolver works with. -
getClassLoader
Description copied from interface:ResourceLoader
Expose theClassLoader
used by thisResourceLoader
.Clients which need to access the
ClassLoader
directly can do so in a uniform manner with theResourceLoader
, rather than relying on the thread contextClassLoader
.- Specified by:
getClassLoader
in interfaceResourceLoader
- Returns:
- the
ClassLoader
(onlynull
if even the systemClassLoader
isn't accessible) - See Also:
-
setPathMatcher
Set thePathMatcher
implementation to use for this resource pattern resolver.Default is
AntPathMatcher
.- See Also:
-
getPathMatcher
Return thePathMatcher
that this resource pattern resolver uses. -
getResource
Description copied from interface:ResourceLoader
Return aResource
handle for the specified resource location.The handle should always be a reusable resource descriptor, allowing for multiple
InputStreamSource.getInputStream()
calls.- Must support fully qualified URLs, e.g. "file:C:/test.dat".
- Must support classpath pseudo-URLs, e.g. "classpath:test.dat".
- Should support relative file paths, e.g. "WEB-INF/test.dat". (This will be implementation-specific, typically provided by an ApplicationContext implementation.)
Note that a
Resource
handle does not imply an existing resource; you need to invokeResource.exists()
to check for existence.- Specified by:
getResource
in interfaceResourceLoader
- Parameters:
location
- the resource location- Returns:
- a corresponding
Resource
handle (nevernull
) - See Also:
-
getResources
Description copied from interface:ResourcePatternResolver
Resolve the given location pattern intoResource
objects.Overlapping resource entries that point to the same physical resource should be avoided, as far as possible. The result should have set semantics.
- Specified by:
getResources
in interfaceResourcePatternResolver
- Parameters:
locationPattern
- the location pattern to resolve- Returns:
- the corresponding
Resource
objects - Throws:
IOException
- in case of I/O errors
-
findAllClassPathResources
Find all class location resources with the given location via the ClassLoader.Delegates to
doFindAllClassPathResources(String)
.- Parameters:
location
- the absolute path within the class path- Returns:
- the result as Resource array
- Throws:
IOException
- in case of I/O errors- See Also:
-
doFindAllClassPathResources
Find all class path resources with the given path via the configuredClassLoader
.Called by
findAllClassPathResources(String)
.- Parameters:
path
- the absolute path within the class path (never a leading slash)- Returns:
- a mutable Set of matching Resource instances
- Throws:
IOException
- Since:
- 4.1.1
-
convertClassLoaderURL
Convert the given URL as returned from the configuredClassLoader
into aResource
, applying to path lookups without a pattern (seefindAllClassPathResources(java.lang.String)
).As of 6.0.5, the default implementation creates a
FileSystemResource
in case of the "file" protocol or aUrlResource
otherwise, matching the outcome of pattern-based class path traversal in the same resource layout, as well as matching the outcome of module path searches.- Parameters:
url
- a URL as returned from the configured ClassLoader- Returns:
- the corresponding Resource object
- See Also:
-
addAllClassLoaderJarRoots
Search allURLClassLoader
URLs for jar file references and add each to the given set of resources in the form of a pointer to the root of the jar file content.- Parameters:
classLoader
- the ClassLoader to search (including its ancestors)result
- the set of resources to add jar roots to- Since:
- 4.1.1
-
addClassPathManifestEntries
Determine jar file references fromClass-Path
manifest entries (which are added to thejava.class.path
JVM system property by the system class loader) and add each to the given set of resources in the form of a pointer to the root of the jar file content.- Parameters:
result
- the set of resources to add jar roots to- Since:
- 4.3
-
findPathMatchingResources
Find all resources that match the given location pattern via the Ant-stylePathMatcher
.Supports resources in OSGi bundles, JBoss VFS, jar files, zip files, and file systems.
- Parameters:
locationPattern
- the location pattern to match- Returns:
- the result as Resource array
- Throws:
IOException
- in case of I/O errors- See Also:
-
determineRootDir
Determine the root directory for the given location.Used for determining the starting point for file matching, resolving the root directory location to be passed into
getResources(String)
, with the remainder of the location to be used as the sub pattern.Will return "/WEB-INF/" for the location "/WEB-INF/*.xml", for example.
- Parameters:
location
- the location to check- Returns:
- the part of the location that denotes the root directory
- See Also:
-
resolveRootDirResource
Resolve the supplied root directory resource for path matching.By default,
findPathMatchingResources(String)
resolves Equinox OSGi "bundleresource:" and "bundleentry:" URLs into standard jar file URLs that will be traversed using Spring's standard jar file traversal algorithm.For any custom resolution, override this template method and replace the supplied resource handle accordingly.
The default implementation of this method returns the supplied resource unmodified.
- Parameters:
original
- the resource to resolve- Returns:
- the resolved resource (may be identical to the supplied resource)
- Throws:
IOException
- in case of resolution failure- See Also:
-
isJarResource
Determine if the given resource handle indicates a jar resource that thedoFindPathMatchingJarResources(org.springframework.core.io.Resource, java.net.URL, java.lang.String)
method can handle.findPathMatchingResources(String)
delegates toResourceUtils.isJarURL(URL)
to determine whether the given URL points to a resource in a jar file, and only invokes this method as a fallback.This template method therefore allows for detecting further kinds of jar-like resources — for example, via
instanceof
checks on the resource handle type.The default implementation of this method returns
false
.- Parameters:
resource
- the resource handle to check (usually the root directory to start path matching from)- Returns:
true
if the given resource handle indicates a jar resource- Throws:
IOException
- in case of I/O errors- See Also:
-
doFindPathMatchingJarResources
protected Set<Resource> doFindPathMatchingJarResources(Resource rootDirResource, URL rootDirUrl, String subPattern) throws IOException Find all resources in jar files that match the given location pattern via the Ant-stylePathMatcher
.- Parameters:
rootDirResource
- the root directory as ResourcerootDirUrl
- the pre-resolved root directory URLsubPattern
- the sub pattern to match (below the root directory)- Returns:
- a mutable Set of matching Resource instances
- Throws:
IOException
- in case of I/O errors- Since:
- 4.3
- See Also:
-
getJarFile
Resolve the given jar file URL into a JarFile object.- Throws:
IOException
-
doFindPathMatchingFileResources
protected Set<Resource> doFindPathMatchingFileResources(Resource rootDirResource, String subPattern) throws IOException Find all resources in the file system of the supplied root directory that match the given location sub pattern via the Ant-stylePathMatcher
.- Parameters:
rootDirResource
- the root directory as a ResourcesubPattern
- the sub pattern to match (below the root directory)- Returns:
- a mutable Set of matching Resource instances
- Throws:
IOException
- in case of I/O errors- See Also:
-
findAllModulePathResources
Resolve the given location pattern intoResource
objects for all matching resources found in the module path.The location pattern may be an explicit resource path such as
"com/example/config.xml"
or a pattern such as"com/example/**/config-*.xml"
to be matched using the configuredPathMatcher
.The default implementation scans all modules in the boot layer, excluding system modules.
- Parameters:
locationPattern
- the location pattern to resolve- Returns:
- a modifiable
Set
containing the correspondingResource
objects - Throws:
IOException
- in case of I/O errors- Since:
- 6.0
- See Also:
-