Skip to content

Commit 9b56a8b

Browse files
Use object provider for LoadBalancerRestClientPostProcessor (#1366)
1 parent 246bc32 commit 9b56a8b

File tree

6 files changed

+116
-20
lines changed

6 files changed

+116
-20
lines changed

spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerAutoConfiguration.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
* @author Will Tran
5050
* @author Gang Li
5151
* @author Olga Maciaszek-Sharma
52+
* @author Henning Pöttker
5253
*/
5354
@AutoConfiguration
5455
@Conditional(BlockingRestClassesPresentCondition.class)
@@ -86,17 +87,18 @@ static class DeferringLoadBalancerInterceptorConfig {
8687

8788
@Bean
8889
@ConditionalOnMissingBean
89-
public DeferringLoadBalancerInterceptor deferringLoadBalancerInterceptor(
90+
public static DeferringLoadBalancerInterceptor deferringLoadBalancerInterceptor(
9091
ObjectProvider<BlockingLoadBalancerInterceptor> loadBalancerInterceptorObjectProvider) {
9192
return new DeferringLoadBalancerInterceptor(loadBalancerInterceptorObjectProvider);
9293
}
9394

9495
@Bean
9596
@ConditionalOnBean(DeferringLoadBalancerInterceptor.class)
96-
@ConditionalOnMissingBean
97-
LoadBalancerRestClientBuilderBeanPostProcessor lbRestClientPostProcessor(
98-
DeferringLoadBalancerInterceptor loadBalancerInterceptor, ApplicationContext context) {
99-
return new LoadBalancerRestClientBuilderBeanPostProcessor(loadBalancerInterceptor, context);
97+
@ConditionalOnMissingBean(LoadBalancerRestClientBuilderBeanPostProcessor.class)
98+
static LoadBalancerRestClientBuilderBeanPostProcessor<DeferringLoadBalancerInterceptor> lbRestClientPostProcessor(
99+
ObjectProvider<DeferringLoadBalancerInterceptor> loadBalancerInterceptorProvider,
100+
ApplicationContext context) {
101+
return new LoadBalancerRestClientBuilderBeanPostProcessor<>(loadBalancerInterceptorProvider, context);
100102
}
101103

102104
}

spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRestClientBuilderBeanPostProcessor.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.springframework.cloud.client.loadbalancer;
1818

1919
import org.springframework.beans.BeansException;
20+
import org.springframework.beans.factory.ObjectProvider;
2021
import org.springframework.beans.factory.config.BeanPostProcessor;
2122
import org.springframework.context.ApplicationContext;
2223
import org.springframework.http.client.ClientHttpRequestInterceptor;
@@ -29,15 +30,21 @@
2930
* @author Olga Maciaszek-Sharma
3031
* @since 4.1.0
3132
*/
32-
public class LoadBalancerRestClientBuilderBeanPostProcessor implements BeanPostProcessor {
33+
public class LoadBalancerRestClientBuilderBeanPostProcessor<T extends ClientHttpRequestInterceptor>
34+
implements BeanPostProcessor {
3335

34-
private final ClientHttpRequestInterceptor loadBalancerInterceptor;
36+
private final ObjectProvider<T> loadBalancerInterceptorProvider;
3537

3638
private final ApplicationContext context;
3739

38-
public LoadBalancerRestClientBuilderBeanPostProcessor(ClientHttpRequestInterceptor loadBalancerInterceptor,
40+
public LoadBalancerRestClientBuilderBeanPostProcessor(T loadBalancerInterceptor, ApplicationContext context) {
41+
this.loadBalancerInterceptorProvider = new SimpleObjectProvider<>(loadBalancerInterceptor);
42+
this.context = context;
43+
}
44+
45+
public LoadBalancerRestClientBuilderBeanPostProcessor(ObjectProvider<T> loadBalancerInterceptorProvider,
3946
ApplicationContext context) {
40-
this.loadBalancerInterceptor = loadBalancerInterceptor;
47+
this.loadBalancerInterceptorProvider = loadBalancerInterceptorProvider;
4148
this.context = context;
4249
}
4350

@@ -47,7 +54,11 @@ public Object postProcessBeforeInitialization(Object bean, String beanName) thro
4754
if (context.findAnnotationOnBean(beanName, LoadBalanced.class) == null) {
4855
return bean;
4956
}
50-
((RestClient.Builder) bean).requestInterceptor(loadBalancerInterceptor);
57+
ClientHttpRequestInterceptor interceptor = loadBalancerInterceptorProvider.getIfAvailable();
58+
if (interceptor == null) {
59+
throw new IllegalStateException(ClientHttpRequestInterceptor.class.getSimpleName() + " not available.");
60+
}
61+
((RestClient.Builder) bean).requestInterceptor(interceptor);
5162
}
5263
return bean;
5364
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright 2012-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cloud.client.loadbalancer;
18+
19+
import org.springframework.beans.BeansException;
20+
import org.springframework.beans.factory.ObjectProvider;
21+
import org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerWebClientBuilderBeanPostProcessor;
22+
23+
/**
24+
* Wrapper for {@link ObjectProvider}. Added to use for a workaround in
25+
* {@link LoadBalancerWebClientBuilderBeanPostProcessor}.
26+
*
27+
* @param <T> type of the object to fetch
28+
* @author Spencer Gibb
29+
* @deprecated for removal in 4.0
30+
*/
31+
@Deprecated(forRemoval = true)
32+
public class SimpleObjectProvider<T> implements ObjectProvider<T> {
33+
34+
private final T object;
35+
36+
public SimpleObjectProvider(T object) {
37+
this.object = object;
38+
}
39+
40+
@Override
41+
public T getObject(Object... args) throws BeansException {
42+
return this.object;
43+
}
44+
45+
@Override
46+
public T getIfAvailable() throws BeansException {
47+
return this.object;
48+
}
49+
50+
@Override
51+
public T getIfUnique() throws BeansException {
52+
return this.object;
53+
}
54+
55+
@Override
56+
public T getObject() throws BeansException {
57+
return this.object;
58+
}
59+
60+
}

spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/DeferringLoadBalancerExchangeFilterFunction.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2024 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.
@@ -55,7 +55,7 @@ void tryResolveDelegate() {
5555
if (delegate == null) {
5656
delegate = exchangeFilterFunctionProvider.getIfAvailable();
5757
if (delegate == null) {
58-
throw new IllegalStateException("ReactorLoadBalancerExchangeFilterFunction not available.");
58+
throw new IllegalStateException("LoadBalancer ExchangeFilterFunction not available.");
5959
}
6060
}
6161
}

spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerBeanPostProcessorAutoConfiguration.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2024 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.
@@ -39,16 +39,19 @@
3939
* beans.
4040
*
4141
* @author Olga Maciaszek-Sharma
42+
* @author Henning Pöttker
4243
* @since 2.2.0
4344
*/
4445
@Configuration(proxyBeanMethods = false)
4546
@ConditionalOnClass(WebClient.class)
4647
@Conditional(LoadBalancerBeanPostProcessorAutoConfiguration.OnAnyLoadBalancerImplementationPresentCondition.class)
4748
public class LoadBalancerBeanPostProcessorAutoConfiguration {
4849

50+
@SuppressWarnings("rawtypes")
4951
@Bean
50-
public LoadBalancerWebClientBuilderBeanPostProcessor loadBalancerWebClientBuilderBeanPostProcessor(
51-
DeferringLoadBalancerExchangeFilterFunction deferringExchangeFilterFunction, ApplicationContext context) {
52+
public static LoadBalancerWebClientBuilderBeanPostProcessor loadBalancerWebClientBuilderBeanPostProcessor(
53+
ObjectProvider<DeferringLoadBalancerExchangeFilterFunction> deferringExchangeFilterFunction,
54+
ApplicationContext context) {
5255
return new LoadBalancerWebClientBuilderBeanPostProcessor(deferringExchangeFilterFunction, context);
5356
}
5457

@@ -58,7 +61,7 @@ protected static class ReactorDeferringLoadBalancerFilterConfig {
5861

5962
@Bean
6063
@Primary
61-
DeferringLoadBalancerExchangeFilterFunction<LoadBalancedExchangeFilterFunction> reactorDeferringLoadBalancerExchangeFilterFunction(
64+
static DeferringLoadBalancerExchangeFilterFunction<LoadBalancedExchangeFilterFunction> reactorDeferringLoadBalancerExchangeFilterFunction(
6265
ObjectProvider<LoadBalancedExchangeFilterFunction> exchangeFilterFunctionProvider) {
6366
return new DeferringLoadBalancerExchangeFilterFunction<>(exchangeFilterFunctionProvider);
6467
}

spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerWebClientBuilderBeanPostProcessor.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2024 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.
@@ -17,8 +17,10 @@
1717
package org.springframework.cloud.client.loadbalancer.reactive;
1818

1919
import org.springframework.beans.BeansException;
20+
import org.springframework.beans.factory.ObjectProvider;
2021
import org.springframework.beans.factory.config.BeanPostProcessor;
2122
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
23+
import org.springframework.cloud.client.loadbalancer.SimpleObjectProvider;
2224
import org.springframework.context.ApplicationContext;
2325
import org.springframework.web.reactive.function.client.WebClient;
2426

@@ -30,15 +32,28 @@
3032
* @author Olga Maciaszek-Sharma
3133
* @since 2.2.0
3234
*/
35+
@SuppressWarnings({ "removal", "rawtypes" })
3336
public class LoadBalancerWebClientBuilderBeanPostProcessor implements BeanPostProcessor {
3437

35-
private final DeferringLoadBalancerExchangeFilterFunction exchangeFilterFunction;
38+
private final ObjectProvider<DeferringLoadBalancerExchangeFilterFunction> exchangeFilterFunctionObjectProvider;
3639

3740
private final ApplicationContext context;
3841

42+
/**
43+
* @deprecated in favour of
44+
* {@link LoadBalancerWebClientBuilderBeanPostProcessor#LoadBalancerWebClientBuilderBeanPostProcessor(ObjectProvider, ApplicationContext)}
45+
*/
46+
@Deprecated(forRemoval = true)
3947
public LoadBalancerWebClientBuilderBeanPostProcessor(
4048
DeferringLoadBalancerExchangeFilterFunction exchangeFilterFunction, ApplicationContext context) {
41-
this.exchangeFilterFunction = exchangeFilterFunction;
49+
this.exchangeFilterFunctionObjectProvider = new SimpleObjectProvider<>(exchangeFilterFunction);
50+
this.context = context;
51+
}
52+
53+
public LoadBalancerWebClientBuilderBeanPostProcessor(
54+
ObjectProvider<DeferringLoadBalancerExchangeFilterFunction> exchangeFilterFunction,
55+
ApplicationContext context) {
56+
this.exchangeFilterFunctionObjectProvider = exchangeFilterFunction;
4257
this.context = context;
4358
}
4459

@@ -48,7 +63,12 @@ public Object postProcessBeforeInitialization(Object bean, String beanName) thro
4863
if (context.findAnnotationOnBean(beanName, LoadBalanced.class) == null) {
4964
return bean;
5065
}
51-
((WebClient.Builder) bean).filter(exchangeFilterFunction);
66+
DeferringLoadBalancerExchangeFilterFunction exchangeFilterFunction = exchangeFilterFunctionObjectProvider
67+
.getIfAvailable();
68+
if (exchangeFilterFunction == null) {
69+
throw new IllegalStateException("LoadBalancerExchangeFilterFunction not found");
70+
}
71+
((WebClient.Builder) bean).filter(exchangeFilterFunctionObjectProvider.getIfAvailable());
5272
}
5373
return bean;
5474
}

0 commit comments

Comments
 (0)