215215 */
216216public class PathMatchingResourcePatternResolver implements ResourcePatternResolver {
217217
218+ private static final Resource [] EMPTY_RESOURCE_ARRAY = {};
219+
218220 private static final Log logger = LogFactory .getLog (PathMatchingResourcePatternResolver .class );
219221
220222 /**
@@ -257,6 +259,8 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
257259
258260 private PathMatcher pathMatcher = new AntPathMatcher ();
259261
262+ private boolean useCaches = true ;
263+
260264 private final Map <String , Resource []> rootDirCache = new ConcurrentHashMap <>();
261265
262266 private final Map <String , NavigableSet <String >> jarEntriesCache = new ConcurrentHashMap <>();
@@ -331,6 +335,22 @@ public PathMatcher getPathMatcher() {
331335 return this .pathMatcher ;
332336 }
333337
338+ /**
339+ * Specify whether this resolver should use jar caches. Default is {@code true}.
340+ * <p>Switch this flag to {@code false} in order to avoid any jar caching, at
341+ * the {@link JarURLConnection} level as well as within this resolver instance.
342+ * <p>Note that {@link JarURLConnection#setDefaultUseCaches} can be turned off
343+ * independently. This resolver-level setting is designed to only enforce
344+ * {@code JarURLConnection#setUseCaches(false)} if necessary but otherwise
345+ * leaves the JVM-level default in place.
346+ * @since 6.1.19
347+ * @see JarURLConnection#setUseCaches
348+ * @see #clearCache()
349+ */
350+ public void setUseCaches (boolean useCaches ) {
351+ this .useCaches = useCaches ;
352+ }
353+
334354
335355 @ Override
336356 public Resource getResource (String location ) {
@@ -354,7 +374,7 @@ public Resource[] getResources(String locationPattern) throws IOException {
354374 // all class path resources with the given name
355375 Collections .addAll (resources , findAllClassPathResources (locationPatternWithoutPrefix ));
356376 }
357- return resources .toArray (new Resource [ 0 ] );
377+ return resources .toArray (EMPTY_RESOURCE_ARRAY );
358378 }
359379 else {
360380 // Generally only look for a pattern after a prefix here,
@@ -398,7 +418,7 @@ protected Resource[] findAllClassPathResources(String location) throws IOExcepti
398418 if (logger .isTraceEnabled ()) {
399419 logger .trace ("Resolved class path location [" + path + "] to resources " + result );
400420 }
401- return result .toArray (new Resource [ 0 ] );
421+ return result .toArray (EMPTY_RESOURCE_ARRAY );
402422 }
403423
404424 /**
@@ -535,7 +555,9 @@ protected void addClassPathManifestEntries(Set<Resource> result) {
535555 Set <ClassPathManifestEntry > entries = this .manifestEntriesCache ;
536556 if (entries == null ) {
537557 entries = getClassPathManifestEntries ();
538- this .manifestEntriesCache = entries ;
558+ if (this .useCaches ) {
559+ this .manifestEntriesCache = entries ;
560+ }
539561 }
540562 for (ClassPathManifestEntry entry : entries ) {
541563 if (!result .contains (entry .resource ()) &&
@@ -687,7 +709,9 @@ else if (commonPrefix.equals(rootDirPath)) {
687709 if (rootDirResources == null ) {
688710 // Lookup for specific directory, creating a cache entry for it.
689711 rootDirResources = getResources (rootDirPath );
690- this .rootDirCache .put (rootDirPath , rootDirResources );
712+ if (this .useCaches ) {
713+ this .rootDirCache .put (rootDirPath , rootDirResources );
714+ }
691715 }
692716 }
693717
@@ -719,7 +743,7 @@ else if (ResourceUtils.isJarURL(rootDirUrl) || isJarResource(rootDirResource)) {
719743 if (logger .isTraceEnabled ()) {
720744 logger .trace ("Resolved location pattern [" + locationPattern + "] to resources " + result );
721745 }
722- return result .toArray (new Resource [ 0 ] );
746+ return result .toArray (EMPTY_RESOURCE_ARRAY );
723747 }
724748
725749 /**
@@ -840,6 +864,9 @@ protected Set<Resource> doFindPathMatchingJarResources(Resource rootDirResource,
840864
841865 if (con instanceof JarURLConnection jarCon ) {
842866 // Should usually be the case for traditional JAR files.
867+ if (!this .useCaches ) {
868+ jarCon .setUseCaches (false );
869+ }
843870 try {
844871 jarFile = jarCon .getJarFile ();
845872 jarFileUrl = jarCon .getJarFileURL ().toExternalForm ();
@@ -903,8 +930,10 @@ protected Set<Resource> doFindPathMatchingJarResources(Resource rootDirResource,
903930 }
904931 }
905932 }
906- // Cache jar entries in TreeSet for efficient searching on re-encounter.
907- this .jarEntriesCache .put (jarFileUrl , entriesCache );
933+ if (this .useCaches ) {
934+ // Cache jar entries in TreeSet for efficient searching on re-encounter.
935+ this .jarEntriesCache .put (jarFileUrl , entriesCache );
936+ }
908937 return result ;
909938 }
910939 finally {
0 commit comments