diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfiguration.java index be7e3e3dda4..96218e0fe3d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfiguration.java @@ -17,6 +17,7 @@ package org.springframework.boot.autoconfigure.web.reactive; import java.time.Duration; +import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -163,14 +164,14 @@ public class WebFluxAutoConfiguration { private final ObjectProvider codecCustomizers; - private final ResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer; + private final ObjectProvider resourceHandlerRegistrationCustomizers; private final ObjectProvider viewResolvers; public WebFluxConfig(Environment environment, WebProperties webProperties, WebFluxProperties webFluxProperties, ListableBeanFactory beanFactory, ObjectProvider resolvers, ObjectProvider codecCustomizers, - ObjectProvider resourceHandlerRegistrationCustomizer, + ObjectProvider resourceHandlerRegistrationCustomizers, ObjectProvider viewResolvers) { this.environment = environment; this.resourceProperties = webProperties.getResources(); @@ -178,7 +179,7 @@ public class WebFluxAutoConfiguration { this.beanFactory = beanFactory; this.argumentResolvers = resolvers; this.codecCustomizers = codecCustomizers; - this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizer.getIfAvailable(); + this.resourceHandlerRegistrationCustomizers = resourceHandlerRegistrationCustomizers; this.viewResolvers = viewResolvers; } @@ -210,19 +211,22 @@ public class WebFluxAutoConfiguration { logger.debug("Default resource handling disabled"); return; } + List resourceHandlerRegistrationCustomizers = this.resourceHandlerRegistrationCustomizers + .orderedStream() + .toList(); String webjarsPathPattern = this.webFluxProperties.getWebjarsPathPattern(); if (!registry.hasMappingForPattern(webjarsPathPattern)) { ResourceHandlerRegistration registration = registry.addResourceHandler(webjarsPathPattern) .addResourceLocations("classpath:/META-INF/resources/webjars/"); configureResourceCaching(registration); - customizeResourceHandlerRegistration(registration); + resourceHandlerRegistrationCustomizers.forEach((customizer) -> customizer.customize(registration)); } String staticPathPattern = this.webFluxProperties.getStaticPathPattern(); if (!registry.hasMappingForPattern(staticPathPattern)) { ResourceHandlerRegistration registration = registry.addResourceHandler(staticPathPattern) .addResourceLocations(this.resourceProperties.getStaticLocations()); configureResourceCaching(registration); - customizeResourceHandlerRegistration(registration); + resourceHandlerRegistrationCustomizers.forEach((customizer) -> customizer.customize(registration)); } } @@ -247,12 +251,6 @@ public class WebFluxAutoConfiguration { ApplicationConversionService.addBeans(registry, this.beanFactory); } - private void customizeResourceHandlerRegistration(ResourceHandlerRegistration registration) { - if (this.resourceHandlerRegistrationCustomizer != null) { - this.resourceHandlerRegistrationCustomizer.customize(registration); - } - } - } /** diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfigurationTests.java index 0c33a4dacd4..09f3c40478a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfigurationTests.java @@ -90,6 +90,7 @@ import org.springframework.web.reactive.HandlerMapping; import org.springframework.web.reactive.accept.RequestedContentTypeResolver; import org.springframework.web.reactive.config.BlockingExecutionConfigurer; import org.springframework.web.reactive.config.DelegatingWebFluxConfiguration; +import org.springframework.web.reactive.config.ResourceHandlerRegistration; import org.springframework.web.reactive.config.WebFluxConfigurationSupport; import org.springframework.web.reactive.config.WebFluxConfigurer; import org.springframework.web.reactive.function.server.support.RouterFunctionMapping; @@ -122,6 +123,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.then; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; /** * Tests for {@link WebFluxAutoConfiguration}. @@ -182,6 +184,18 @@ class WebFluxAutoConfigurationTests { }); } + @Test + void shouldCustomizeResources() { + this.contextRunner.withUserConfiguration(ResourceHandlerRegistrationCustomizers.class).run((context) -> { + ResourceHandlerRegistrationCustomizer customizer1 = context + .getBean("firstResourceHandlerRegistrationCustomizer", ResourceHandlerRegistrationCustomizer.class); + ResourceHandlerRegistrationCustomizer customizer2 = context + .getBean("secondResourceHandlerRegistrationCustomizer", ResourceHandlerRegistrationCustomizer.class); + then(customizer1).should(times(2)).customize(any(ResourceHandlerRegistration.class)); + then(customizer2).should(times(2)).customize(any(ResourceHandlerRegistration.class)); + }); + } + @Test void shouldRegisterResourceHandlerMapping() { this.contextRunner.run((context) -> { @@ -845,6 +859,21 @@ class WebFluxAutoConfigurationTests { } + @Configuration(proxyBeanMethods = false) + static class ResourceHandlerRegistrationCustomizers { + + @Bean + ResourceHandlerRegistrationCustomizer firstResourceHandlerRegistrationCustomizer() { + return mock(ResourceHandlerRegistrationCustomizer.class); + } + + @Bean + ResourceHandlerRegistrationCustomizer secondResourceHandlerRegistrationCustomizer() { + return mock(ResourceHandlerRegistrationCustomizer.class); + } + + } + @Configuration(proxyBeanMethods = false) static class ViewResolvers {