mirror of
https://github.com/spring-projects/spring-boot.git
synced 2026-10-02 15:29:05 +00:00
Support virtual threading with JDK HTTP clients
Update JDK HTTP Clients so that the use virtual threads when `Threading.VIRTUAL` is active. See gh-46404 Signed-off-by: Sangmin Park <sangmins930@gmail.com>
This commit is contained in:
committed by
Phillip Webb
parent
53ff2de58e
commit
e32e3359c2
+7
@@ -19,6 +19,7 @@ package org.springframework.boot.http.client;
|
||||
import java.net.http.HttpClient;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
@@ -75,6 +76,12 @@ public final class JdkClientHttpRequestFactoryBuilder
|
||||
this.httpClientBuilder.withCustomizer(httpClientCustomizer));
|
||||
}
|
||||
|
||||
public JdkClientHttpRequestFactoryBuilder enableVirtualThreadExecutor() {
|
||||
return this.withHttpClientCustomizer(builder ->
|
||||
builder.executor(Executors.newVirtualThreadPerTaskExecutor())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JdkClientHttpRequestFactory createClientHttpRequestFactory(ClientHttpRequestFactorySettings settings) {
|
||||
HttpClient httpClient = this.httpClientBuilder.build(asHttpClientSettings(settings.withReadTimeout(null)));
|
||||
|
||||
+18
-2
@@ -24,10 +24,13 @@ import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnThreading;
|
||||
import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.thread.Threading;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder;
|
||||
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings;
|
||||
import org.springframework.boot.http.client.JdkClientHttpRequestFactoryBuilder;
|
||||
import org.springframework.boot.ssl.SslBundles;
|
||||
import org.springframework.boot.util.LambdaSafe;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -64,18 +67,31 @@ public final class HttpClientAutoConfiguration implements BeanClassLoaderAware {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
ClientHttpRequestFactoryBuilder<?> clientHttpRequestFactoryBuilder(
|
||||
@ConditionalOnThreading(Threading.PLATFORM)
|
||||
ClientHttpRequestFactoryBuilder<?> clientHttpRequestFactoryBuilderOnPlatform(
|
||||
ObjectProvider<ClientHttpRequestFactoryBuilderCustomizer<?>> clientHttpRequestFactoryBuilderCustomizers) {
|
||||
ClientHttpRequestFactoryBuilder<?> builder = this.factories.builder(this.beanClassLoader);
|
||||
return customize(builder, clientHttpRequestFactoryBuilderCustomizers.orderedStream().toList());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnThreading(Threading.VIRTUAL)
|
||||
ClientHttpRequestFactoryBuilder<?> clientHttpRequestFactoryBuilderOnVirtual(
|
||||
ObjectProvider<ClientHttpRequestFactoryBuilderCustomizer<?>> clientHttpRequestFactoryBuilderCustomizers) {
|
||||
ClientHttpRequestFactoryBuilder<?> builder = this.factories.builder(this.beanClassLoader);
|
||||
if (builder instanceof JdkClientHttpRequestFactoryBuilder jdk) {
|
||||
return customize(jdk.enableVirtualThreadExecutor(), clientHttpRequestFactoryBuilderCustomizers.orderedStream().toList());
|
||||
}
|
||||
return customize(builder, clientHttpRequestFactoryBuilderCustomizers.orderedStream().toList());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private ClientHttpRequestFactoryBuilder<?> customize(ClientHttpRequestFactoryBuilder<?> builder,
|
||||
List<ClientHttpRequestFactoryBuilderCustomizer<?>> customizers) {
|
||||
ClientHttpRequestFactoryBuilder<?>[] builderReference = { builder };
|
||||
LambdaSafe.callbacks(ClientHttpRequestFactoryBuilderCustomizer.class, customizers, builderReference[0])
|
||||
.invoke((customizer) -> builderReference[0] = customizer.customize(builderReference[0]));
|
||||
.invoke((customizer) -> builderReference[0] = customizer.customize(builderReference[0]));
|
||||
return builderReference[0];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user