Skip to content

Commit 2f2dfea

Browse files
Add support for virtual and platform threading in HttpClient configuration
1 parent a7207d0 commit 2f2dfea

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

module/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/JdkClientHttpRequestFactoryBuilder.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.net.http.HttpClient;
2020
import java.util.Collection;
2121
import java.util.List;
22+
import java.util.concurrent.Executors;
2223
import java.util.function.Consumer;
2324

2425
import org.springframework.boot.context.properties.PropertyMapper;
@@ -73,6 +74,12 @@ public JdkClientHttpRequestFactoryBuilder withHttpClientCustomizer(
7374
this.httpClientBuilder.withCustomizer(httpClientCustomizer));
7475
}
7576

77+
public JdkClientHttpRequestFactoryBuilder enableVirtualThreadExecutor() {
78+
return this.withHttpClientCustomizer(builder ->
79+
builder.executor(Executors.newVirtualThreadPerTaskExecutor())
80+
);
81+
}
82+
7683
@Override
7784
protected JdkClientHttpRequestFactory createClientHttpRequestFactory(ClientHttpRequestFactorySettings settings) {
7885
HttpClient httpClient = this.httpClientBuilder.build(asHttpClientSettings(settings.withReadTimeout(null)));

module/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/HttpClientAutoConfiguration.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,13 @@
2424
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
2525
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
2626
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
27+
import org.springframework.boot.autoconfigure.condition.ConditionalOnThreading;
2728
import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration;
29+
import org.springframework.boot.autoconfigure.thread.Threading;
2830
import org.springframework.boot.context.properties.EnableConfigurationProperties;
2931
import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder;
3032
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings;
33+
import org.springframework.boot.http.client.JdkClientHttpRequestFactoryBuilder;
3134
import org.springframework.boot.ssl.SslBundles;
3235
import org.springframework.boot.util.LambdaSafe;
3336
import org.springframework.context.annotation.Bean;
@@ -63,18 +66,31 @@ public void setBeanClassLoader(ClassLoader classLoader) {
6366

6467
@Bean
6568
@ConditionalOnMissingBean
66-
ClientHttpRequestFactoryBuilder<?> clientHttpRequestFactoryBuilder(
69+
@ConditionalOnThreading(Threading.PLATFORM)
70+
ClientHttpRequestFactoryBuilder<?> clientHttpRequestFactoryBuilderOnPlatform(
6771
ObjectProvider<ClientHttpRequestFactoryBuilderCustomizer<?>> clientHttpRequestFactoryBuilderCustomizers) {
6872
ClientHttpRequestFactoryBuilder<?> builder = this.factories.builder(this.beanClassLoader);
6973
return customize(builder, clientHttpRequestFactoryBuilderCustomizers.orderedStream().toList());
7074
}
7175

76+
@Bean
77+
@ConditionalOnMissingBean
78+
@ConditionalOnThreading(Threading.VIRTUAL)
79+
ClientHttpRequestFactoryBuilder<?> clientHttpRequestFactoryBuilderOnVirtual(
80+
ObjectProvider<ClientHttpRequestFactoryBuilderCustomizer<?>> clientHttpRequestFactoryBuilderCustomizers) {
81+
ClientHttpRequestFactoryBuilder<?> builder = this.factories.builder(this.beanClassLoader);
82+
if (builder instanceof JdkClientHttpRequestFactoryBuilder jdk) {
83+
return customize(jdk.enableVirtualThreadExecutor(), clientHttpRequestFactoryBuilderCustomizers.orderedStream().toList());
84+
}
85+
return customize(builder, clientHttpRequestFactoryBuilderCustomizers.orderedStream().toList());
86+
}
87+
7288
@SuppressWarnings("unchecked")
7389
private ClientHttpRequestFactoryBuilder<?> customize(ClientHttpRequestFactoryBuilder<?> builder,
7490
List<ClientHttpRequestFactoryBuilderCustomizer<?>> customizers) {
7591
ClientHttpRequestFactoryBuilder<?>[] builderReference = { builder };
7692
LambdaSafe.callbacks(ClientHttpRequestFactoryBuilderCustomizer.class, customizers, builderReference[0])
77-
.invoke((customizer) -> builderReference[0] = customizer.customize(builderReference[0]));
93+
.invoke((customizer) -> builderReference[0] = customizer.customize(builderReference[0]));
7894
return builderReference[0];
7995
}
8096

0 commit comments

Comments
 (0)