Skip to content

Commit

Permalink
Use object provider for LoadBalancerRestClientPostProcessor (spring-c…
Browse files Browse the repository at this point in the history
  • Loading branch information
OlgaMaciaszek authored Jul 31, 2024
1 parent 246bc32 commit 9b56a8b
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
* @author Will Tran
* @author Gang Li
* @author Olga Maciaszek-Sharma
* @author Henning Pöttker
*/
@AutoConfiguration
@Conditional(BlockingRestClassesPresentCondition.class)
Expand Down Expand Up @@ -86,17 +87,18 @@ static class DeferringLoadBalancerInterceptorConfig {

@Bean
@ConditionalOnMissingBean
public DeferringLoadBalancerInterceptor deferringLoadBalancerInterceptor(
public static DeferringLoadBalancerInterceptor deferringLoadBalancerInterceptor(
ObjectProvider<BlockingLoadBalancerInterceptor> loadBalancerInterceptorObjectProvider) {
return new DeferringLoadBalancerInterceptor(loadBalancerInterceptorObjectProvider);
}

@Bean
@ConditionalOnBean(DeferringLoadBalancerInterceptor.class)
@ConditionalOnMissingBean
LoadBalancerRestClientBuilderBeanPostProcessor lbRestClientPostProcessor(
DeferringLoadBalancerInterceptor loadBalancerInterceptor, ApplicationContext context) {
return new LoadBalancerRestClientBuilderBeanPostProcessor(loadBalancerInterceptor, context);
@ConditionalOnMissingBean(LoadBalancerRestClientBuilderBeanPostProcessor.class)
static LoadBalancerRestClientBuilderBeanPostProcessor<DeferringLoadBalancerInterceptor> lbRestClientPostProcessor(
ObjectProvider<DeferringLoadBalancerInterceptor> loadBalancerInterceptorProvider,
ApplicationContext context) {
return new LoadBalancerRestClientBuilderBeanPostProcessor<>(loadBalancerInterceptorProvider, context);
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.springframework.cloud.client.loadbalancer;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.http.client.ClientHttpRequestInterceptor;
Expand All @@ -29,15 +30,21 @@
* @author Olga Maciaszek-Sharma
* @since 4.1.0
*/
public class LoadBalancerRestClientBuilderBeanPostProcessor implements BeanPostProcessor {
public class LoadBalancerRestClientBuilderBeanPostProcessor<T extends ClientHttpRequestInterceptor>
implements BeanPostProcessor {

private final ClientHttpRequestInterceptor loadBalancerInterceptor;
private final ObjectProvider<T> loadBalancerInterceptorProvider;

private final ApplicationContext context;

public LoadBalancerRestClientBuilderBeanPostProcessor(ClientHttpRequestInterceptor loadBalancerInterceptor,
public LoadBalancerRestClientBuilderBeanPostProcessor(T loadBalancerInterceptor, ApplicationContext context) {
this.loadBalancerInterceptorProvider = new SimpleObjectProvider<>(loadBalancerInterceptor);
this.context = context;
}

public LoadBalancerRestClientBuilderBeanPostProcessor(ObjectProvider<T> loadBalancerInterceptorProvider,
ApplicationContext context) {
this.loadBalancerInterceptor = loadBalancerInterceptor;
this.loadBalancerInterceptorProvider = loadBalancerInterceptorProvider;
this.context = context;
}

Expand All @@ -47,7 +54,11 @@ public Object postProcessBeforeInitialization(Object bean, String beanName) thro
if (context.findAnnotationOnBean(beanName, LoadBalanced.class) == null) {
return bean;
}
((RestClient.Builder) bean).requestInterceptor(loadBalancerInterceptor);
ClientHttpRequestInterceptor interceptor = loadBalancerInterceptorProvider.getIfAvailable();
if (interceptor == null) {
throw new IllegalStateException(ClientHttpRequestInterceptor.class.getSimpleName() + " not available.");
}
((RestClient.Builder) bean).requestInterceptor(interceptor);
}
return bean;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright 2012-2024 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.cloud.client.loadbalancer;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerWebClientBuilderBeanPostProcessor;

/**
* Wrapper for {@link ObjectProvider}. Added to use for a workaround in
* {@link LoadBalancerWebClientBuilderBeanPostProcessor}.
*
* @param <T> type of the object to fetch
* @author Spencer Gibb
* @deprecated for removal in 4.0
*/
@Deprecated(forRemoval = true)
public class SimpleObjectProvider<T> implements ObjectProvider<T> {

private final T object;

public SimpleObjectProvider(T object) {
this.object = object;
}

@Override
public T getObject(Object... args) throws BeansException {
return this.object;
}

@Override
public T getIfAvailable() throws BeansException {
return this.object;
}

@Override
public T getIfUnique() throws BeansException {
return this.object;
}

@Override
public T getObject() throws BeansException {
return this.object;
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2024 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.
Expand Down Expand Up @@ -55,7 +55,7 @@ void tryResolveDelegate() {
if (delegate == null) {
delegate = exchangeFilterFunctionProvider.getIfAvailable();
if (delegate == null) {
throw new IllegalStateException("ReactorLoadBalancerExchangeFilterFunction not available.");
throw new IllegalStateException("LoadBalancer ExchangeFilterFunction not available.");
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2024 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.
Expand Down Expand Up @@ -39,16 +39,19 @@
* beans.
*
* @author Olga Maciaszek-Sharma
* @author Henning Pöttker
* @since 2.2.0
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(WebClient.class)
@Conditional(LoadBalancerBeanPostProcessorAutoConfiguration.OnAnyLoadBalancerImplementationPresentCondition.class)
public class LoadBalancerBeanPostProcessorAutoConfiguration {

@SuppressWarnings("rawtypes")
@Bean
public LoadBalancerWebClientBuilderBeanPostProcessor loadBalancerWebClientBuilderBeanPostProcessor(
DeferringLoadBalancerExchangeFilterFunction deferringExchangeFilterFunction, ApplicationContext context) {
public static LoadBalancerWebClientBuilderBeanPostProcessor loadBalancerWebClientBuilderBeanPostProcessor(
ObjectProvider<DeferringLoadBalancerExchangeFilterFunction> deferringExchangeFilterFunction,
ApplicationContext context) {
return new LoadBalancerWebClientBuilderBeanPostProcessor(deferringExchangeFilterFunction, context);
}

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

@Bean
@Primary
DeferringLoadBalancerExchangeFilterFunction<LoadBalancedExchangeFilterFunction> reactorDeferringLoadBalancerExchangeFilterFunction(
static DeferringLoadBalancerExchangeFilterFunction<LoadBalancedExchangeFilterFunction> reactorDeferringLoadBalancerExchangeFilterFunction(
ObjectProvider<LoadBalancedExchangeFilterFunction> exchangeFilterFunctionProvider) {
return new DeferringLoadBalancerExchangeFilterFunction<>(exchangeFilterFunctionProvider);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2024 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.
Expand All @@ -17,8 +17,10 @@
package org.springframework.cloud.client.loadbalancer.reactive;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.SimpleObjectProvider;
import org.springframework.context.ApplicationContext;
import org.springframework.web.reactive.function.client.WebClient;

Expand All @@ -30,15 +32,28 @@
* @author Olga Maciaszek-Sharma
* @since 2.2.0
*/
@SuppressWarnings({ "removal", "rawtypes" })
public class LoadBalancerWebClientBuilderBeanPostProcessor implements BeanPostProcessor {

private final DeferringLoadBalancerExchangeFilterFunction exchangeFilterFunction;
private final ObjectProvider<DeferringLoadBalancerExchangeFilterFunction> exchangeFilterFunctionObjectProvider;

private final ApplicationContext context;

/**
* @deprecated in favour of
* {@link LoadBalancerWebClientBuilderBeanPostProcessor#LoadBalancerWebClientBuilderBeanPostProcessor(ObjectProvider, ApplicationContext)}
*/
@Deprecated(forRemoval = true)
public LoadBalancerWebClientBuilderBeanPostProcessor(
DeferringLoadBalancerExchangeFilterFunction exchangeFilterFunction, ApplicationContext context) {
this.exchangeFilterFunction = exchangeFilterFunction;
this.exchangeFilterFunctionObjectProvider = new SimpleObjectProvider<>(exchangeFilterFunction);
this.context = context;
}

public LoadBalancerWebClientBuilderBeanPostProcessor(
ObjectProvider<DeferringLoadBalancerExchangeFilterFunction> exchangeFilterFunction,
ApplicationContext context) {
this.exchangeFilterFunctionObjectProvider = exchangeFilterFunction;
this.context = context;
}

Expand All @@ -48,7 +63,12 @@ public Object postProcessBeforeInitialization(Object bean, String beanName) thro
if (context.findAnnotationOnBean(beanName, LoadBalanced.class) == null) {
return bean;
}
((WebClient.Builder) bean).filter(exchangeFilterFunction);
DeferringLoadBalancerExchangeFilterFunction exchangeFilterFunction = exchangeFilterFunctionObjectProvider
.getIfAvailable();
if (exchangeFilterFunction == null) {
throw new IllegalStateException("LoadBalancerExchangeFilterFunction not found");
}
((WebClient.Builder) bean).filter(exchangeFilterFunctionObjectProvider.getIfAvailable());
}
return bean;
}
Expand Down

0 comments on commit 9b56a8b

Please sign in to comment.