diff --git a/spring-core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java b/spring-core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java index 8aff467ca2f3..273e02033978 100644 --- a/spring-core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java +++ b/spring-core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java @@ -19,6 +19,10 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.io.UncheckedIOException; +import java.lang.module.ModuleFinder; +import java.lang.module.ModuleReader; +import java.lang.module.ResolvedModule; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.net.JarURLConnection; @@ -32,9 +36,13 @@ import java.util.Comparator; import java.util.Enumeration; import java.util.LinkedHashSet; +import java.util.Objects; import java.util.Set; +import java.util.function.Predicate; import java.util.jar.JarEntry; import java.util.jar.JarFile; +import java.util.stream.Collectors; +import java.util.stream.Stream; import java.util.zip.ZipException; import org.apache.commons.logging.Log; @@ -140,6 +148,14 @@ * *
Other notes: * + *
As of Spring Framework 6.0, if {@link #getResources(String)} is invoked + * with a location pattern using the "classpath*:" prefix it will first search + * all modules in the {@linkplain ModuleLayer#boot() boot layer}, excluding + * {@linkplain ModuleFinder#ofSystem() system modules}. It will then search the + * classpath using {@link Classloader} APIs as described previously and return the + * combined results. Consequently, some of the limitations of classpath searches + * may not apply when applications are deployed as modules. + * *
WARNING: Note that "{@code 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
@@ -174,6 +190,7 @@
* @author Marius Bogoevici
* @author Costin Leau
* @author Phillip Webb
+ * @author Sam Brannen
* @since 1.0.2
* @see #CLASSPATH_ALL_URL_PREFIX
* @see org.springframework.util.AntPathMatcher
@@ -184,6 +201,23 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
private static final Log logger = LogFactory.getLog(PathMatchingResourcePatternResolver.class);
+ /**
+ * {@link Set} of {@linkplain ModuleFinder#ofSystem() system module} names.
+ * @since 6.0
+ * @see #isNotSystemModule
+ */
+ private static final Set The location pattern may be an explicit resource path such as
+ * {@code "com/example/config.xml"} or a pattern such as
+ * The default implementation scans all modules in the {@linkplain ModuleLayer#boot()
+ * boot layer}, excluding {@linkplain ModuleFinder#ofSystem() system modules}.
+ * @param locationPattern the location pattern to resolve
+ * @return a modifiable {@code Set} containing the corresponding {@code Resource}
+ * objects
+ * @throws IOException in case of I/O errors
+ * @since 6.0
+ * @see ModuleLayer#boot()
+ * @see ModuleFinder#ofSystem()
+ * @see ModuleReader
+ * @see PathMatcher#match(String, String)
+ */
+ protected Set This interface also defines a {@code "classpath*:"} resource prefix for all
- * matching resources from the class path. Note that the resource location may
- * also contain placeholders — for example {@code "/beans-*.xml"}. JAR files
- * or different directories in the class path can contain multiple files of the
- * same name.
+ * This interface also defines a {@value #CLASSPATH_ALL_URL_PREFIX} resource
+ * prefix for all matching resources from the module path and the class path. Note
+ * that the resource location may also contain placeholders — for example
+ * {@code "/beans-*.xml"}. JAR files or different directories in the module path
+ * or class path can contain multiple files of the same name.
*
* @author Juergen Hoeller
+ * @author Sam Brannen
* @since 1.0.2
* @see org.springframework.core.io.Resource
* @see org.springframework.core.io.ResourceLoader
@@ -57,10 +58,13 @@
public interface ResourcePatternResolver extends ResourceLoader {
/**
- * Pseudo URL prefix for all matching resources from the class path: "classpath*:"
- * This differs from ResourceLoader's classpath URL prefix in that it
- * retrieves all matching resources for a given name (e.g. "/beans.xml"),
- * for example in the root of all deployed JAR files.
+ * Pseudo URL prefix for all matching resources from the class path: {@code "classpath*:"}.
+ * This differs from ResourceLoader's {@code "classpath:"} URL prefix in
+ * that it retrieves all matching resources for a given path — for
+ * example, to locate all "beans.xml" files in the root of all deployed JAR
+ * files you can use the location pattern {@code "classpath*:/beans.xml"}.
+ * As of Spring Framework 6.0, the semantics for the {@code "classpath*:"}
+ * prefix have been expanded to include the module path as well as the class path.
* @see org.springframework.core.io.ResourceLoader#CLASSPATH_URL_PREFIX
*/
String CLASSPATH_ALL_URL_PREFIX = "classpath*:";
"com/example/**/config-*.xml"
to be matched using the
+ * configured {@link #getPathMatcher() PathMatcher}.
+ *