Add ClientHttpRequestFactoryBuilderCustomizer support
Add `ClientHttpRequestFactoryBuilderCustomizer` interface that can be used to customize the `ClientHttpRequestFactoryBuilder`. Closes gh-44987
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.autoconfigure.http.client;
|
||||
|
||||
import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder;
|
||||
|
||||
/**
|
||||
* Customizer that can be used to modify the auto-configured
|
||||
* {@link ClientHttpRequestFactoryBuilder} when its type matches.
|
||||
*
|
||||
* @param <B> the builder type
|
||||
* @author Phillip Webb
|
||||
* @since 3.5.0
|
||||
*/
|
||||
public interface ClientHttpRequestFactoryBuilderCustomizer<B extends ClientHttpRequestFactoryBuilder<?>> {
|
||||
|
||||
/**
|
||||
* Customize the given builder.
|
||||
* @param builder the builder to customize
|
||||
* @return the customized builder
|
||||
*/
|
||||
B customize(B builder);
|
||||
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.boot.autoconfigure.http.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
@@ -29,6 +31,7 @@ import org.springframework.boot.http.client.ClientHttpRequestFactorySettings.Red
|
||||
import org.springframework.boot.http.client.HttpClientSettings;
|
||||
import org.springframework.boot.http.client.HttpRedirects;
|
||||
import org.springframework.boot.ssl.SslBundles;
|
||||
import org.springframework.boot.util.LambdaSafe;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||
@@ -48,8 +51,19 @@ public class HttpClientAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
ClientHttpRequestFactoryBuilder<?> clientHttpRequestFactoryBuilder(HttpClientProperties httpClientProperties) {
|
||||
return httpClientProperties.factoryBuilder();
|
||||
ClientHttpRequestFactoryBuilder<?> clientHttpRequestFactoryBuilder(HttpClientProperties httpClientProperties,
|
||||
ObjectProvider<ClientHttpRequestFactoryBuilderCustomizer<?>> clientHttpRequestFactoryBuilderCustomizers) {
|
||||
ClientHttpRequestFactoryBuilder<?> builder = httpClientProperties.factoryBuilder();
|
||||
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]));
|
||||
return builderReference[0];
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -27,9 +27,14 @@ import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration;
|
||||
import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder;
|
||||
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings;
|
||||
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings.Redirects;
|
||||
import org.springframework.boot.http.client.HttpComponentsClientHttpRequestFactoryBuilder;
|
||||
import org.springframework.boot.http.client.JettyClientHttpRequestFactoryBuilder;
|
||||
import org.springframework.boot.http.client.SimpleClientHttpRequestFactoryBuilder;
|
||||
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;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -89,4 +94,30 @@ class HttpClientAutoConfigurationTests {
|
||||
.doesNotHaveBean(ClientHttpRequestFactorySettings.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void clientHttpRequestFactoryBuilderCustomizersAreApplied() {
|
||||
this.contextRunner.withUserConfiguration(ClientHttpRequestFactoryBuilderCustomizersConfiguration.class)
|
||||
.run((context) -> {
|
||||
ClientHttpRequestFactory factory = context.getBean(ClientHttpRequestFactoryBuilder.class).build();
|
||||
assertThat(factory).extracting("connectTimeout").isEqualTo(5L);
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class ClientHttpRequestFactoryBuilderCustomizersConfiguration {
|
||||
|
||||
@Bean
|
||||
ClientHttpRequestFactoryBuilderCustomizer<HttpComponentsClientHttpRequestFactoryBuilder> httpComponentsCustomizer() {
|
||||
return (builder) -> builder.withCustomizer((factory) -> factory.setConnectTimeout(5));
|
||||
}
|
||||
|
||||
@Bean
|
||||
ClientHttpRequestFactoryBuilderCustomizer<JettyClientHttpRequestFactoryBuilder> jettyCustomizer() {
|
||||
return (builder) -> {
|
||||
throw new IllegalStateException();
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -272,7 +272,7 @@ spring:
|
||||
redirects: dont-follow
|
||||
----
|
||||
|
||||
For more complex customizations, you can declare your own javadoc:org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder[] bean which will cause auto-configuration to back off.
|
||||
For more complex customizations, you can use javadoc:org.springframework.boot.autoconfigure.http.client.ClientHttpRequestFactoryBuilderCustomizer[] or declare your own javadoc:org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder[] bean which will cause auto-configuration to back off.
|
||||
This can be useful when you need to customize some of the internals of the underlying HTTP library.
|
||||
|
||||
For example, the following will use a JDK client configured with a specific javadoc:java.net.ProxySelector[]:
|
||||
|
||||
Reference in New Issue
Block a user