From b57b6c4e275c72b8bbdc3497a357536e4357205c Mon Sep 17 00:00:00 2001 From: Dmytro Nosan Date: Mon, 4 Aug 2025 22:52:56 +0300 Subject: [PATCH] Restore use of ReactorResourceFactory This commit configures ReactorClientHttpConnectorBuilder with the ReactorResourceFactory bean from the context. See gh-46673 Signed-off-by: Dmytro Nosan --- .../ClientHttpConnectorAutoConfiguration.java | 10 +++++++++ .../ClientHttpConnectorAutoConfiguration.java | 5 ----- ...ntHttpConnectorAutoConfigurationTests.java | 21 ++++++++++++++++++- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/ClientHttpConnectorAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/ClientHttpConnectorAutoConfiguration.java index 7c2770d0bdd..e074beff63a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/ClientHttpConnectorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/ClientHttpConnectorAutoConfiguration.java @@ -31,6 +31,7 @@ import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.http.client.reactive.ClientHttpConnectorBuilder; import org.springframework.boot.http.client.reactive.ClientHttpConnectorSettings; +import org.springframework.boot.http.client.reactive.ReactorClientHttpConnectorBuilder; import org.springframework.boot.ssl.SslBundles; import org.springframework.boot.util.LambdaSafe; import org.springframework.context.annotation.Bean; @@ -38,6 +39,8 @@ import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Lazy; +import org.springframework.core.annotation.Order; +import org.springframework.http.client.ReactorResourceFactory; import org.springframework.http.client.reactive.ClientHttpConnector; /** @@ -103,6 +106,13 @@ public class ClientHttpConnectorAutoConfiguration implements BeanClassLoaderAwar @Import(ReactorNettyConfigurations.ReactorResourceFactoryConfiguration.class) static class ReactorNetty { + @Bean + @Order(0) + ClientHttpConnectorBuilderCustomizer reactorResourceFactoryClientHttpConnectorBuilderCustomizer( + ReactorResourceFactory reactorResourceFactory) { + return (builder) -> builder.withReactorResourceFactory(reactorResourceFactory); + } + } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorAutoConfiguration.java index 87663ef25c0..635e6f62775 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorAutoConfiguration.java @@ -25,13 +25,10 @@ import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.http.client.reactive.ClientHttpConnectorBuilderCustomizer; -import org.springframework.boot.autoconfigure.reactor.netty.ReactorNettyConfigurations.ReactorResourceFactoryConfiguration; import org.springframework.boot.http.client.reactive.ReactorClientHttpConnectorBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; import org.springframework.core.annotation.Order; -import org.springframework.http.client.ReactorResourceFactory; import org.springframework.web.reactive.function.client.WebClient; /** @@ -52,14 +49,12 @@ public class ClientHttpConnectorAutoConfiguration { @Configuration(proxyBeanMethods = false) @ConditionalOnClass(HttpClient.class) - @Import(ReactorResourceFactoryConfiguration.class) @SuppressWarnings("removal") static class ReactorNetty { @Bean @Order(0) ClientHttpConnectorBuilderCustomizer reactorNettyHttpClientMapperClientHttpConnectorBuilderCustomizer( - ReactorResourceFactory reactorResourceFactory, ObjectProvider mapperProvider) { return applyMappers(mapperProvider.orderedStream().toList()); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/reactive/ClientHttpConnectorAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/reactive/ClientHttpConnectorAutoConfigurationTests.java index a3af3b6cfe6..6dd305e1313 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/reactive/ClientHttpConnectorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/reactive/ClientHttpConnectorAutoConfigurationTests.java @@ -23,6 +23,7 @@ import java.util.List; import org.apache.hc.client5.http.impl.async.HttpAsyncClients; import org.junit.jupiter.api.Test; import reactor.netty.http.client.HttpClient; +import reactor.netty.resources.LoopResources; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -114,6 +115,21 @@ class ClientHttpConnectorAutoConfigurationTests { assertThat(context).hasSingleBean(ClientHttpConnector.class); assertThat(context).hasSingleBean(ReactorResourceFactory.class); assertThat(context).hasBean("customReactorResourceFactory"); + ClientHttpConnector connector = context.getBean(ClientHttpConnector.class); + assertThat(connector).extracting("httpClient.config.loopResources") + .isEqualTo(context.getBean("customReactorResourceFactory", ReactorResourceFactory.class) + .getLoopResources()); + }); + } + + @Test + void shouldUseReactorResourceFactory() { + this.contextRunner.run((context) -> { + assertThat(context).hasSingleBean(ClientHttpConnector.class); + assertThat(context).hasSingleBean(ReactorResourceFactory.class); + ClientHttpConnector connector = context.getBean(ClientHttpConnector.class); + assertThat(connector).extracting("httpClient.config.loopResources") + .isEqualTo(context.getBean(ReactorResourceFactory.class).getLoopResources()); }); } @@ -190,7 +206,10 @@ class ClientHttpConnectorAutoConfigurationTests { @Bean ReactorResourceFactory customReactorResourceFactory() { - return new ReactorResourceFactory(); + ReactorResourceFactory reactorResourceFactory = new ReactorResourceFactory(); + reactorResourceFactory.setUseGlobalResources(false); + reactorResourceFactory.setLoopResources(LoopResources.create("custom-loop", 1, true)); + return reactorResourceFactory; } }