11/*
2- * Copyright 2012-2024 the original author or authors.
2+ * Copyright 2012-2025 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
@@ -132,8 +132,8 @@ public static ResourceLoader get(ResourceLoader resourceLoader) {
132132 * class loader at the time this call is made.
133133 * @param resourceLoader the delegate resource loader
134134 * @param preferFileResolution if file based resolution is preferred over
135- * {@code ServletContextResource} or {@link ClassPathResource} when no resource prefix
136- * is provided.
135+ * {@code ServletContextResource}, {@code FilteredReactiveWebContextResource} or
136+ * {@link ClassPathResource} when no resource prefix is provided.
137137 * @return a {@link ResourceLoader} instance
138138 * @since 3.4.1
139139 */
@@ -212,28 +212,31 @@ private static class ProtocolResolvingResourceLoader implements ResourceLoader {
212212
213213 private static final String SERVLET_CONTEXT_RESOURCE_CLASS_NAME = "org.springframework.web.context.support.ServletContextResource" ;
214214
215+ private static final String FILTERED_REACTIVE_WEB_CONTEXT_RESOURCE_CLASS_NAME = "org.springframework.boot.web.reactive.context.FilteredReactiveWebContextResource" ;
216+
215217 private final ResourceLoader resourceLoader ;
216218
217219 private final List <ProtocolResolver > protocolResolvers ;
218220
219221 private final boolean preferFileResolution ;
220222
221- private Class <?> servletContextResourceClass ;
223+ private final Class <?> servletContextResourceClass ;
224+
225+ private final Class <?> filteredReactiveWebContextResourceClass ;
222226
223227 ProtocolResolvingResourceLoader (ResourceLoader resourceLoader , List <ProtocolResolver > protocolResolvers ,
224228 boolean preferFileResolution ) {
225229 this .resourceLoader = resourceLoader ;
226230 this .protocolResolvers = protocolResolvers ;
227231 this .preferFileResolution = preferFileResolution ;
228- this .servletContextResourceClass = resolveServletContextResourceClass (
229- resourceLoader .getClass ().getClassLoader ());
232+ this .servletContextResourceClass = resolveServletContextResourceClass (resourceLoader );
233+ this .filteredReactiveWebContextResourceClass = resolveFilteredReactiveWebContextResourceClass (
234+ resourceLoader );
230235 }
231236
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 );
237+ @ Override
238+ public ClassLoader getClassLoader () {
239+ return this .resourceLoader .getClassLoader ();
237240 }
238241
239242 @ Override
@@ -247,24 +250,47 @@ public Resource getResource(String location) {
247250 }
248251 }
249252 Resource resource = this .resourceLoader .getResource (location );
250- if (this .preferFileResolution
251- && (isClassPathResourceByPath (location , resource ) || isServletResource (resource ))) {
252- resource = new ApplicationResource (location );
253+ if (shouldUseFileResolution (location , resource )) {
254+ return new ApplicationResource (location );
253255 }
254256 return resource ;
255257 }
256258
259+ private boolean shouldUseFileResolution (String location , Resource resource ) {
260+ if (!this .preferFileResolution ) {
261+ return false ;
262+ }
263+ return isClassPathResourceByPath (location , resource ) || isServletContextResource (resource )
264+ || isFilteredReactiveWebContextResource (resource );
265+ }
266+
257267 private boolean isClassPathResourceByPath (String location , Resource resource ) {
258268 return (resource instanceof ClassPathResource ) && !location .startsWith (CLASSPATH_URL_PREFIX );
259269 }
260270
261- private boolean isServletResource (Resource resource ) {
262- return this .servletContextResourceClass != null && this .servletContextResourceClass .isInstance (resource );
271+ private boolean isServletContextResource (Resource resource ) {
272+ return ( this .servletContextResourceClass != null ) && this .servletContextResourceClass .isInstance (resource );
263273 }
264274
265- @ Override
266- public ClassLoader getClassLoader () {
267- return this .resourceLoader .getClassLoader ();
275+ private boolean isFilteredReactiveWebContextResource (Resource resource ) {
276+ return (this .filteredReactiveWebContextResourceClass != null )
277+ && this .filteredReactiveWebContextResourceClass .isInstance (resource );
278+ }
279+
280+ private static Class <?> resolveServletContextResourceClass (ResourceLoader resourceLoader ) {
281+ return resolveClassName (SERVLET_CONTEXT_RESOURCE_CLASS_NAME , resourceLoader .getClass ().getClassLoader ());
282+ }
283+
284+ private static Class <?> resolveFilteredReactiveWebContextResourceClass (ResourceLoader resourceLoader ) {
285+ return resolveClassName (FILTERED_REACTIVE_WEB_CONTEXT_RESOURCE_CLASS_NAME ,
286+ resourceLoader .getClass ().getClassLoader ());
287+ }
288+
289+ private static Class <?> resolveClassName (String clazz , ClassLoader classLoader ) {
290+ if (!ClassUtils .isPresent (clazz , classLoader )) {
291+ return null ;
292+ }
293+ return ClassUtils .resolveClassName (clazz , classLoader );
268294 }
269295
270296 }
0 commit comments