Skip to content

Commit 8c31cfe

Browse files
committed
Merge pull request #44982 from nosan
* pr/44982: Polish RestClientAutoConfiguration and RestClientBuilderConfigurer Closes gh-44982
2 parents ec055de + 5e966f9 commit 8c31cfe

File tree

4 files changed

+100
-36
lines changed

4 files changed

+100
-36
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

+14-17
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.
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.boot.autoconfigure.web.client;
1818

19+
import java.util.Collections;
1920
import java.util.List;
2021

2122
import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder;
@@ -32,21 +33,21 @@
3233
*/
3334
public class RestClientBuilderConfigurer {
3435

35-
private ClientHttpRequestFactoryBuilder<?> requestFactoryBuilder;
36+
private final ClientHttpRequestFactoryBuilder<?> requestFactoryBuilder;
3637

37-
private ClientHttpRequestFactorySettings requestFactorySettings;
38+
private final ClientHttpRequestFactorySettings requestFactorySettings;
3839

39-
private List<RestClientCustomizer> customizers;
40+
private final List<RestClientCustomizer> customizers;
4041

41-
void setRequestFactoryBuilder(ClientHttpRequestFactoryBuilder<?> requestFactoryBuilder) {
42-
this.requestFactoryBuilder = requestFactoryBuilder;
42+
public RestClientBuilderConfigurer() {
43+
this(ClientHttpRequestFactoryBuilder.detect(), ClientHttpRequestFactorySettings.defaults(),
44+
Collections.emptyList());
4345
}
4446

45-
void setRequestFactorySettings(ClientHttpRequestFactorySettings requestFactorySettings) {
47+
RestClientBuilderConfigurer(ClientHttpRequestFactoryBuilder<?> requestFactoryBuilder,
48+
ClientHttpRequestFactorySettings requestFactorySettings, List<RestClientCustomizer> customizers) {
49+
this.requestFactoryBuilder = requestFactoryBuilder;
4650
this.requestFactorySettings = requestFactorySettings;
47-
}
48-
49-
void setRestClientCustomizers(List<RestClientCustomizer> customizers) {
5051
this.customizers = customizers;
5152
}
5253

@@ -57,18 +58,14 @@ void setRestClientCustomizers(List<RestClientCustomizer> customizers) {
5758
* @return the configured builder
5859
*/
5960
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));
61+
builder.requestFactory(this.requestFactoryBuilder.build(this.requestFactorySettings));
6362
applyCustomizers(builder);
6463
return builder;
6564
}
6665

6766
private void applyCustomizers(Builder builder) {
68-
if (this.customizers != null) {
69-
for (RestClientCustomizer customizer : this.customizers) {
70-
customizer.customize(builder);
71-
}
67+
for (RestClientCustomizer customizer : this.customizers) {
68+
customizer.customize(builder);
7269
}
7370
}
7471

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)