From 4feb1faf3aa3f517b499318b2ad771969776ad6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Thu, 27 Nov 2025 09:54:26 +0100 Subject: [PATCH] Polish "Relax conditions to create HttpService client with RestClient" See gh-48274 --- .../HttpServiceClientAutoConfiguration.java | 2 - .../NotReactiveWebApplicationCondition.java | 41 -------------- ...irtualThreadsExecutorEnabledCondition.java | 54 ------------------- ...tpServiceClientAutoConfigurationTests.java | 34 ------------ 4 files changed, 131 deletions(-) delete mode 100644 module/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/NotReactiveWebApplicationCondition.java delete mode 100644 module/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/NotReactiveWebApplicationOrVirtualThreadsExecutorEnabledCondition.java diff --git a/module/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/HttpServiceClientAutoConfiguration.java b/module/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/HttpServiceClientAutoConfiguration.java index 0605da85fb3..7f3118f8491 100644 --- a/module/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/HttpServiceClientAutoConfiguration.java +++ b/module/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/HttpServiceClientAutoConfiguration.java @@ -29,7 +29,6 @@ import org.springframework.boot.restclient.RestClientCustomizer; import org.springframework.boot.restclient.autoconfigure.RestClientAutoConfiguration; import org.springframework.boot.ssl.SslBundles; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Conditional; import org.springframework.core.io.ResourceLoader; import org.springframework.web.client.RestClient; import org.springframework.web.client.support.RestClientAdapter; @@ -46,7 +45,6 @@ import org.springframework.web.service.registry.HttpServiceProxyRegistry; @AutoConfiguration(after = { ImperativeHttpClientAutoConfiguration.class, RestClientAutoConfiguration.class }) @ConditionalOnClass(RestClientAdapter.class) @ConditionalOnBean(HttpServiceProxyRegistry.class) -@Conditional(NotReactiveWebApplicationOrVirtualThreadsExecutorEnabledCondition.class) @EnableConfigurationProperties(HttpServiceClientProperties.class) public final class HttpServiceClientAutoConfiguration { diff --git a/module/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/NotReactiveWebApplicationCondition.java b/module/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/NotReactiveWebApplicationCondition.java deleted file mode 100644 index f25fba42c26..00000000000 --- a/module/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/NotReactiveWebApplicationCondition.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.restclient.autoconfigure.service; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.condition.NoneNestedConditions; -import org.springframework.boot.autoconfigure.condition.SpringBootCondition; - -/** - * {@link SpringBootCondition} that applies only when running in a non-reactive web - * application. - * - * @author Phillip Webb - */ -class NotReactiveWebApplicationCondition extends NoneNestedConditions { - - NotReactiveWebApplicationCondition() { - super(ConfigurationPhase.PARSE_CONFIGURATION); - } - - @ConditionalOnWebApplication(type = Type.REACTIVE) - private static final class ReactiveWebApplication { - - } - -} diff --git a/module/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/NotReactiveWebApplicationOrVirtualThreadsExecutorEnabledCondition.java b/module/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/NotReactiveWebApplicationOrVirtualThreadsExecutorEnabledCondition.java deleted file mode 100644 index 0c0347d036b..00000000000 --- a/module/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/NotReactiveWebApplicationOrVirtualThreadsExecutorEnabledCondition.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.restclient.autoconfigure.service; - -import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnThreading; -import org.springframework.boot.autoconfigure.condition.SpringBootCondition; -import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration; -import org.springframework.boot.thread.Threading; -import org.springframework.context.annotation.Conditional; - -/** - * {@link SpringBootCondition} that applies when running in a non-reactive web application - * or virtual threads are enabled. - * - * Package-private by design to avoid exposing conditions as public API. Should be kept in - * sync with - * {@code org.springframework.boot.restclient.autoconfigure.NotReactiveWebApplicationOrVirtualThreadsExecutorEnabledCondition}. - * - * @author Dmitry Sulman - */ -class NotReactiveWebApplicationOrVirtualThreadsExecutorEnabledCondition extends AnyNestedCondition { - - NotReactiveWebApplicationOrVirtualThreadsExecutorEnabledCondition() { - super(ConfigurationPhase.REGISTER_BEAN); - } - - @Conditional(NotReactiveWebApplicationCondition.class) - private static final class NotReactiveWebApplication { - - } - - @ConditionalOnThreading(Threading.VIRTUAL) - @ConditionalOnBean(name = TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME) - private static final class VirtualThreadsExecutorEnabled { - - } - -} diff --git a/module/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/service/HttpServiceClientAutoConfigurationTests.java b/module/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/service/HttpServiceClientAutoConfigurationTests.java index 4b1f86beba0..11d0ca19bae 100644 --- a/module/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/service/HttpServiceClientAutoConfigurationTests.java +++ b/module/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/service/HttpServiceClientAutoConfigurationTests.java @@ -35,7 +35,6 @@ import org.mockito.ArgumentCaptor; import org.springframework.aop.Advisor; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration; import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; import org.springframework.boot.http.client.HttpClientSettings; import org.springframework.boot.http.client.HttpRedirects; @@ -44,7 +43,6 @@ import org.springframework.boot.http.client.autoconfigure.imperative.ImperativeH import org.springframework.boot.restclient.RestClientCustomizer; import org.springframework.boot.restclient.autoconfigure.RestClientAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.ClientHttpRequestFactory; @@ -56,12 +54,10 @@ import org.springframework.web.client.RestClient.Builder; import org.springframework.web.client.support.RestClientHttpServiceGroupConfigurer; import org.springframework.web.service.annotation.GetExchange; import org.springframework.web.service.registry.HttpServiceGroup; -import org.springframework.web.service.registry.HttpServiceGroup.ClientType; import org.springframework.web.service.registry.HttpServiceGroupConfigurer.ClientCallback; import org.springframework.web.service.registry.HttpServiceGroupConfigurer.Groups; import org.springframework.web.service.registry.HttpServiceProxyRegistry; import org.springframework.web.service.registry.ImportHttpServices; -import org.springframework.web.util.UriComponentsBuilder; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; @@ -221,23 +217,6 @@ class HttpServiceClientAutoConfigurationTests { .run((context) -> assertThat(context).doesNotHaveBean(HttpServiceProxyRegistry.class)); } - @Test - void restClientServiceClientsApplyPropertiesWhenReactiveWithVirtualThreads() { - new ReactiveWebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(HttpServiceClientAutoConfiguration.class, - ImperativeHttpClientAutoConfiguration.class, RestClientAutoConfiguration.class, - TaskExecutionAutoConfiguration.class)) - .withPropertyValues("spring.threads.virtual.enabled=true", - "spring.http.serviceclient.echo.base-url=https://example.com") - .withUserConfiguration(ReactiveHttpClientConfiguration.class) - .run((context) -> { - RestClient restClient = getRestClient(context.getBean(ReactiveTestClient.class)); - UriComponentsBuilder baseUri = (UriComponentsBuilder) Extractors.byName("uriBuilderFactory.baseUri") - .apply(restClient); - assertThat(baseUri.build().toUriString()).isEqualTo("https://example.com"); - }); - } - private HttpClient getJdkHttpClient(Object proxy) { return (HttpClient) Extractors.byName("clientRequestFactory.httpClient").apply(getRestClient(proxy)); } @@ -336,17 +315,4 @@ class HttpServiceClientAutoConfigurationTests { } - @Configuration(proxyBeanMethods = false) - @ImportHttpServices(types = ReactiveTestClient.class, clientType = ClientType.REST_CLIENT, group = "echo") - static class ReactiveHttpClientConfiguration { - - } - - interface ReactiveTestClient { - - @GetExchange("/echo") - String echo(); - - } - }