1
1
/*
2
- * Copyright 2012-2024 the original author or authors.
2
+ * Copyright 2012-2025 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
16
16
17
17
package org .springframework .boot .io ;
18
18
19
+ import java .util .Collections ;
19
20
import java .util .List ;
20
21
21
- import org .springframework .core .io .ClassPathResource ;
22
22
import org .springframework .core .io .ContextResource ;
23
23
import org .springframework .core .io .DefaultResourceLoader ;
24
24
import org .springframework .core .io .FileSystemResource ;
27
27
import org .springframework .core .io .ResourceLoader ;
28
28
import org .springframework .core .io .support .SpringFactoriesLoader ;
29
29
import org .springframework .util .Assert ;
30
- import org .springframework .util .ClassUtils ;
31
30
import org .springframework .util .StringUtils ;
32
31
33
32
/**
@@ -131,9 +130,8 @@ public static ResourceLoader get(ResourceLoader resourceLoader) {
131
130
* {@code spring.factories}. The factories file will be resolved using the default
132
131
* class loader at the time this call is made.
133
132
* @param resourceLoader the delegate resource loader
134
- * @param preferFileResolution if file based resolution is preferred over
135
- * {@code ServletContextResource} or {@link ClassPathResource} when no resource prefix
136
- * is provided.
133
+ * @param preferFileResolution if file based resolution is preferred when a suitable
134
+ * {@link ResourceFilePathResolver} support the resource
137
135
* @return a {@link ResourceLoader} instance
138
136
* @since 3.4.1
139
137
*/
@@ -161,8 +159,10 @@ private static ResourceLoader get(ResourceLoader resourceLoader, SpringFactories
161
159
boolean preferFileResolution ) {
162
160
Assert .notNull (resourceLoader , "'resourceLoader' must not be null" );
163
161
Assert .notNull (springFactoriesLoader , "'springFactoriesLoader' must not be null" );
164
- return new ProtocolResolvingResourceLoader (resourceLoader , springFactoriesLoader .load (ProtocolResolver .class ),
165
- preferFileResolution );
162
+ List <ProtocolResolver > protocolResolvers = springFactoriesLoader .load (ProtocolResolver .class );
163
+ List <ResourceFilePathResolver > filePathResolvers = (preferFileResolution )
164
+ ? springFactoriesLoader .load (ResourceFilePathResolver .class ) : Collections .emptyList ();
165
+ return new ProtocolResolvingResourceLoader (resourceLoader , protocolResolvers , filePathResolvers );
166
166
}
167
167
168
168
/**
@@ -210,30 +210,22 @@ public String getPathWithinContext() {
210
210
*/
211
211
private static class ProtocolResolvingResourceLoader implements ResourceLoader {
212
212
213
- private static final String SERVLET_CONTEXT_RESOURCE_CLASS_NAME = "org.springframework.web.context.support.ServletContextResource" ;
214
-
215
213
private final ResourceLoader resourceLoader ;
216
214
217
215
private final List <ProtocolResolver > protocolResolvers ;
218
216
219
- private final boolean preferFileResolution ;
220
-
221
- private Class <?> servletContextResourceClass ;
217
+ private final List <ResourceFilePathResolver > filePathResolvers ;
222
218
223
219
ProtocolResolvingResourceLoader (ResourceLoader resourceLoader , List <ProtocolResolver > protocolResolvers ,
224
- boolean preferFileResolution ) {
220
+ List < ResourceFilePathResolver > filePathResolvers ) {
225
221
this .resourceLoader = resourceLoader ;
226
222
this .protocolResolvers = protocolResolvers ;
227
- this .preferFileResolution = preferFileResolution ;
228
- this .servletContextResourceClass = resolveServletContextResourceClass (
229
- resourceLoader .getClass ().getClassLoader ());
223
+ this .filePathResolvers = filePathResolvers ;
230
224
}
231
225
232
- private static Class <?> resolveServletContextResourceClass (ClassLoader classLoader ) {
233
- if (!ClassUtils .isPresent (SERVLET_CONTEXT_RESOURCE_CLASS_NAME , classLoader )) {
234
- return null ;
235
- }
236
- return ClassUtils .resolveClassName (SERVLET_CONTEXT_RESOURCE_CLASS_NAME , classLoader );
226
+ @ Override
227
+ public ClassLoader getClassLoader () {
228
+ return this .resourceLoader .getClassLoader ();
237
229
}
238
230
239
231
@ Override
@@ -247,24 +239,18 @@ public Resource getResource(String location) {
247
239
}
248
240
}
249
241
Resource resource = this .resourceLoader .getResource (location );
250
- if (this .preferFileResolution
251
- && (isClassPathResourceByPath (location , resource ) || isServletResource (resource ))) {
252
- resource = new ApplicationResource (location );
253
- }
254
- return resource ;
242
+ String fileSystemPath = getFileSystemPath (location , resource );
243
+ return (fileSystemPath != null ) ? new ApplicationResource (fileSystemPath ) : resource ;
255
244
}
256
245
257
- private boolean isClassPathResourceByPath (String location , Resource resource ) {
258
- return (resource instanceof ClassPathResource ) && !location .startsWith (CLASSPATH_URL_PREFIX );
259
- }
260
-
261
- private boolean isServletResource (Resource resource ) {
262
- return this .servletContextResourceClass != null && this .servletContextResourceClass .isInstance (resource );
263
- }
264
-
265
- @ Override
266
- public ClassLoader getClassLoader () {
267
- return this .resourceLoader .getClassLoader ();
246
+ private String getFileSystemPath (String location , Resource resource ) {
247
+ for (ResourceFilePathResolver filePathResolver : this .filePathResolvers ) {
248
+ String filePath = filePathResolver .resolveFilePath (location , resource );
249
+ if (filePath != null ) {
250
+ return filePath ;
251
+ }
252
+ }
253
+ return null ;
268
254
}
269
255
270
256
}
0 commit comments