Skip to content

Commit e591644

Browse files
committed
Polish RestClientAutoConfiguration and RestClientBuilderConfigurer
Signed-off-by: Dmytro Nosan <dimanosan@gmail.com>
1 parent d0612f5 commit e591644

File tree

4 files changed

+95
-37
lines changed

4 files changed

+95
-37
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/RestClientAutoConfiguration.java

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2024 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -79,11 +79,10 @@ RestClientBuilderConfigurer restClientBuilderConfigurer(
7979
ObjectProvider<ClientHttpRequestFactoryBuilder<?>> clientHttpRequestFactoryBuilder,
8080
ObjectProvider<ClientHttpRequestFactorySettings> clientHttpRequestFactorySettings,
8181
ObjectProvider<RestClientCustomizer> customizerProvider) {
82-
RestClientBuilderConfigurer configurer = new RestClientBuilderConfigurer();
83-
configurer.setRequestFactoryBuilder(clientHttpRequestFactoryBuilder.getIfAvailable());
84-
configurer.setRequestFactorySettings(clientHttpRequestFactorySettings.getIfAvailable());
85-
configurer.setRestClientCustomizers(customizerProvider.orderedStream().toList());
86-
return configurer;
82+
return new RestClientBuilderConfigurer(
83+
clientHttpRequestFactoryBuilder.getIfAvailable(ClientHttpRequestFactoryBuilder::detect),
84+
clientHttpRequestFactorySettings.getIfAvailable(ClientHttpRequestFactorySettings::defaults),
85+
customizerProvider.orderedStream().toList());
8786
}
8887

8988
@Bean

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/RestClientBuilderConfigurer.java

+9-18
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2024 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -32,21 +32,16 @@
3232
*/
3333
public class RestClientBuilderConfigurer {
3434

35-
private ClientHttpRequestFactoryBuilder<?> requestFactoryBuilder;
35+
private final ClientHttpRequestFactoryBuilder<?> requestFactoryBuilder;
3636

37-
private ClientHttpRequestFactorySettings requestFactorySettings;
37+
private final ClientHttpRequestFactorySettings requestFactorySettings;
3838

39-
private List<RestClientCustomizer> customizers;
39+
private final List<RestClientCustomizer> customizers;
4040

41-
void setRequestFactoryBuilder(ClientHttpRequestFactoryBuilder<?> requestFactoryBuilder) {
41+
RestClientBuilderConfigurer(ClientHttpRequestFactoryBuilder<?> requestFactoryBuilder,
42+
ClientHttpRequestFactorySettings requestFactorySettings, List<RestClientCustomizer> customizers) {
4243
this.requestFactoryBuilder = requestFactoryBuilder;
43-
}
44-
45-
void setRequestFactorySettings(ClientHttpRequestFactorySettings requestFactorySettings) {
4644
this.requestFactorySettings = requestFactorySettings;
47-
}
48-
49-
void setRestClientCustomizers(List<RestClientCustomizer> customizers) {
5045
this.customizers = customizers;
5146
}
5247

@@ -57,18 +52,14 @@ void setRestClientCustomizers(List<RestClientCustomizer> customizers) {
5752
* @return the configured builder
5853
*/
5954
public RestClient.Builder configure(RestClient.Builder builder) {
60-
ClientHttpRequestFactoryBuilder<?> requestFactoryBuilder = (this.requestFactoryBuilder != null)
61-
? this.requestFactoryBuilder : ClientHttpRequestFactoryBuilder.detect();
62-
builder.requestFactory(requestFactoryBuilder.build(this.requestFactorySettings));
55+
builder.requestFactory(this.requestFactoryBuilder.build(this.requestFactorySettings));
6356
applyCustomizers(builder);
6457
return builder;
6558
}
6659

6760
private void applyCustomizers(Builder builder) {
68-
if (this.customizers != null) {
69-
for (RestClientCustomizer customizer : this.customizers) {
70-
customizer.customize(builder);
71-
}
61+
for (RestClientCustomizer customizer : this.customizers) {
62+
customizer.customize(builder);
7263
}
7364
}
7465

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/client/RestClientAutoConfigurationTests.java

+55-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2024 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -24,6 +24,9 @@
2424
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
2525
import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration;
2626
import org.springframework.boot.autoconfigure.http.client.HttpClientAutoConfiguration;
27+
import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder;
28+
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings;
29+
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings.Redirects;
2730
import org.springframework.boot.ssl.SslBundles;
2831
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
2932
import org.springframework.boot.web.client.RestClientCustomizer;
@@ -171,6 +174,57 @@ void whenHasFactoryProperty() {
171174
});
172175
}
173176

177+
@Test
178+
void shouldSupplyRestClientBuilderConfigurerWithCustomSettings() {
179+
ClientHttpRequestFactorySettings clientHttpRequestFactorySettings = ClientHttpRequestFactorySettings.defaults()
180+
.withRedirects(Redirects.DONT_FOLLOW);
181+
ClientHttpRequestFactoryBuilder<?> clientHttpRequestFactoryBuilder = mock(
182+
ClientHttpRequestFactoryBuilder.class);
183+
RestClientCustomizer customizer1 = mock(RestClientCustomizer.class);
184+
RestClientCustomizer customizer2 = mock(RestClientCustomizer.class);
185+
HttpMessageConvertersRestClientCustomizer httpMessageConverterCustomizer = mock(
186+
HttpMessageConvertersRestClientCustomizer.class);
187+
this.contextRunner.withBean(ClientHttpRequestFactorySettings.class, () -> clientHttpRequestFactorySettings)
188+
.withBean(ClientHttpRequestFactoryBuilder.class, () -> clientHttpRequestFactoryBuilder)
189+
.withBean("customizer1", RestClientCustomizer.class, () -> customizer1)
190+
.withBean("customizer2", RestClientCustomizer.class, () -> customizer2)
191+
.withBean("httpMessageConverterCustomizer", HttpMessageConvertersRestClientCustomizer.class,
192+
() -> httpMessageConverterCustomizer)
193+
.run((context) -> {
194+
assertThat(context).hasSingleBean(RestClientBuilderConfigurer.class)
195+
.hasSingleBean(ClientHttpRequestFactorySettings.class)
196+
.hasSingleBean(ClientHttpRequestFactoryBuilder.class);
197+
RestClientBuilderConfigurer configurer = context.getBean(RestClientBuilderConfigurer.class);
198+
assertThat(configurer).hasFieldOrPropertyWithValue("requestFactoryBuilder",
199+
clientHttpRequestFactoryBuilder);
200+
assertThat(configurer).hasFieldOrPropertyWithValue("requestFactorySettings",
201+
clientHttpRequestFactorySettings);
202+
assertThat(configurer).hasFieldOrPropertyWithValue("customizers",
203+
List.of(customizer1, customizer2, httpMessageConverterCustomizer));
204+
});
205+
}
206+
207+
@Test
208+
void shouldSupplyRestClientBuilderConfigurerWithAutoConfiguredHttpSettings() {
209+
RestClientCustomizer customizer1 = mock(RestClientCustomizer.class);
210+
RestClientCustomizer customizer2 = mock(RestClientCustomizer.class);
211+
this.contextRunner.withBean("customizer1", RestClientCustomizer.class, () -> customizer1)
212+
.withBean("customizer2", RestClientCustomizer.class, () -> customizer2)
213+
.run((context) -> {
214+
assertThat(context).hasSingleBean(RestClientBuilderConfigurer.class)
215+
.hasSingleBean(ClientHttpRequestFactorySettings.class)
216+
.hasSingleBean(ClientHttpRequestFactoryBuilder.class)
217+
.hasSingleBean(HttpMessageConvertersRestClientCustomizer.class);
218+
RestClientBuilderConfigurer configurer = context.getBean(RestClientBuilderConfigurer.class);
219+
assertThat(configurer).hasFieldOrPropertyWithValue("requestFactoryBuilder",
220+
context.getBean(ClientHttpRequestFactoryBuilder.class));
221+
assertThat(configurer).hasFieldOrPropertyWithValue("requestFactorySettings",
222+
context.getBean(ClientHttpRequestFactorySettings.class));
223+
assertThat(configurer).hasFieldOrPropertyWithValue("customizers", List.of(customizer1, customizer2,
224+
context.getBean(HttpMessageConvertersRestClientCustomizer.class)));
225+
});
226+
}
227+
174228
@Configuration(proxyBeanMethods = false)
175229
static class CodecConfiguration {
176230

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/client/RestClientBuilderConfigurerTests.java

+26-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,11 +19,19 @@
1919
import java.util.List;
2020

2121
import org.junit.jupiter.api.Test;
22+
import org.junit.jupiter.api.extension.ExtendWith;
23+
import org.mockito.Mock;
24+
import org.mockito.junit.jupiter.MockitoExtension;
2225

26+
import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder;
27+
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings;
28+
import org.springframework.boot.ssl.SslBundle;
2329
import org.springframework.boot.web.client.RestClientCustomizer;
30+
import org.springframework.http.client.ClientHttpRequestFactory;
2431
import org.springframework.web.client.RestClient;
2532

26-
import static org.assertj.core.api.Assertions.assertThatCode;
33+
import static org.assertj.core.api.Assertions.assertThat;
34+
import static org.mockito.BDDMockito.given;
2735
import static org.mockito.BDDMockito.then;
2836
import static org.mockito.Mockito.mock;
2937

@@ -32,23 +40,29 @@
3240
*
3341
* @author Moritz Halbritter
3442
*/
43+
@ExtendWith(MockitoExtension.class)
3544
class RestClientBuilderConfigurerTests {
3645

46+
@Mock
47+
private ClientHttpRequestFactoryBuilder<ClientHttpRequestFactory> clientHttpRequestFactoryBuilder;
48+
49+
@Mock
50+
private ClientHttpRequestFactory clientHttpRequestFactory;
51+
3752
@Test
38-
void shouldApplyCustomizers() {
39-
RestClientBuilderConfigurer configurer = new RestClientBuilderConfigurer();
53+
void shouldConfigureRestClientBuilder() {
54+
ClientHttpRequestFactorySettings settings = ClientHttpRequestFactorySettings.ofSslBundle(mock(SslBundle.class));
4055
RestClientCustomizer customizer = mock(RestClientCustomizer.class);
41-
configurer.setRestClientCustomizers(List.of(customizer));
56+
RestClientCustomizer customizer1 = mock(RestClientCustomizer.class);
57+
RestClientBuilderConfigurer configurer = new RestClientBuilderConfigurer(this.clientHttpRequestFactoryBuilder,
58+
settings, List.of(customizer, customizer1));
59+
given(this.clientHttpRequestFactoryBuilder.build(settings)).willReturn(this.clientHttpRequestFactory);
60+
4261
RestClient.Builder builder = RestClient.builder();
4362
configurer.configure(builder);
63+
assertThat(builder.build()).hasFieldOrPropertyWithValue("clientRequestFactory", this.clientHttpRequestFactory);
4464
then(customizer).should().customize(builder);
45-
}
46-
47-
@Test
48-
void shouldSupportNullAsCustomizers() {
49-
RestClientBuilderConfigurer configurer = new RestClientBuilderConfigurer();
50-
configurer.setRestClientCustomizers(null);
51-
assertThatCode(() -> configurer.configure(RestClient.builder())).doesNotThrowAnyException();
65+
then(customizer1).should().customize(builder);
5266
}
5367

5468
}

0 commit comments

Comments
 (0)