215
215
*/
216
216
public class PathMatchingResourcePatternResolver implements ResourcePatternResolver {
217
217
218
+ private static final Resource [] EMPTY_RESOURCE_ARRAY = {};
219
+
218
220
private static final Log logger = LogFactory .getLog (PathMatchingResourcePatternResolver .class );
219
221
220
222
/**
@@ -257,6 +259,8 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
257
259
258
260
private PathMatcher pathMatcher = new AntPathMatcher ();
259
261
262
+ private boolean useCaches = true ;
263
+
260
264
private final Map <String , Resource []> rootDirCache = new ConcurrentHashMap <>();
261
265
262
266
private final Map <String , NavigableSet <String >> jarEntriesCache = new ConcurrentHashMap <>();
@@ -331,6 +335,22 @@ public PathMatcher getPathMatcher() {
331
335
return this .pathMatcher ;
332
336
}
333
337
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
+
334
354
335
355
@ Override
336
356
public Resource getResource (String location ) {
@@ -354,7 +374,7 @@ public Resource[] getResources(String locationPattern) throws IOException {
354
374
// all class path resources with the given name
355
375
Collections .addAll (resources , findAllClassPathResources (locationPatternWithoutPrefix ));
356
376
}
357
- return resources .toArray (new Resource [ 0 ] );
377
+ return resources .toArray (EMPTY_RESOURCE_ARRAY );
358
378
}
359
379
else {
360
380
// Generally only look for a pattern after a prefix here,
@@ -398,7 +418,7 @@ protected Resource[] findAllClassPathResources(String location) throws IOExcepti
398
418
if (logger .isTraceEnabled ()) {
399
419
logger .trace ("Resolved class path location [" + path + "] to resources " + result );
400
420
}
401
- return result .toArray (new Resource [ 0 ] );
421
+ return result .toArray (EMPTY_RESOURCE_ARRAY );
402
422
}
403
423
404
424
/**
@@ -535,7 +555,9 @@ protected void addClassPathManifestEntries(Set<Resource> result) {
535
555
Set <ClassPathManifestEntry > entries = this .manifestEntriesCache ;
536
556
if (entries == null ) {
537
557
entries = getClassPathManifestEntries ();
538
- this .manifestEntriesCache = entries ;
558
+ if (this .useCaches ) {
559
+ this .manifestEntriesCache = entries ;
560
+ }
539
561
}
540
562
for (ClassPathManifestEntry entry : entries ) {
541
563
if (!result .contains (entry .resource ()) &&
@@ -687,7 +709,9 @@ else if (commonPrefix.equals(rootDirPath)) {
687
709
if (rootDirResources == null ) {
688
710
// Lookup for specific directory, creating a cache entry for it.
689
711
rootDirResources = getResources (rootDirPath );
690
- this .rootDirCache .put (rootDirPath , rootDirResources );
712
+ if (this .useCaches ) {
713
+ this .rootDirCache .put (rootDirPath , rootDirResources );
714
+ }
691
715
}
692
716
}
693
717
@@ -719,7 +743,7 @@ else if (ResourceUtils.isJarURL(rootDirUrl) || isJarResource(rootDirResource)) {
719
743
if (logger .isTraceEnabled ()) {
720
744
logger .trace ("Resolved location pattern [" + locationPattern + "] to resources " + result );
721
745
}
722
- return result .toArray (new Resource [ 0 ] );
746
+ return result .toArray (EMPTY_RESOURCE_ARRAY );
723
747
}
724
748
725
749
/**
@@ -840,6 +864,9 @@ protected Set<Resource> doFindPathMatchingJarResources(Resource rootDirResource,
840
864
841
865
if (con instanceof JarURLConnection jarCon ) {
842
866
// Should usually be the case for traditional JAR files.
867
+ if (!this .useCaches ) {
868
+ jarCon .setUseCaches (false );
869
+ }
843
870
try {
844
871
jarFile = jarCon .getJarFile ();
845
872
jarFileUrl = jarCon .getJarFileURL ().toExternalForm ();
@@ -903,8 +930,10 @@ protected Set<Resource> doFindPathMatchingJarResources(Resource rootDirResource,
903
930
}
904
931
}
905
932
}
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
+ }
908
937
return result ;
909
938
}
910
939
finally {
0 commit comments