From 95b7d2f91e084855b482ae40a7691d42219a7382 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Fri, 13 Jan 2023 15:40:29 +0100 Subject: [PATCH] Do not run BlockingLoadBalancerClientAutoConfiguration or LoadBalancerCacheAutoConfiguration when load-balancing disabled. Fixes gh-1114. --- ...ngLoadBalancerClientAutoConfiguration.java | 2 ++ .../LoadBalancerCacheAutoConfiguration.java | 27 ++++++++++++++++--- ...dBalancerClientAutoConfigurationTests.java | 8 ++++++ ...adBalancerCacheAutoConfigurationTests.java | 10 +++++++ 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/BlockingLoadBalancerClientAutoConfiguration.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/BlockingLoadBalancerClientAutoConfiguration.java index 9d0b934e..51de2a02 100644 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/BlockingLoadBalancerClientAutoConfiguration.java +++ b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/BlockingLoadBalancerClientAutoConfiguration.java @@ -21,6 +21,7 @@ import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.AsyncLoadBalancerAutoConfiguration; @@ -52,6 +53,7 @@ import org.springframework.web.client.RestTemplate; @AutoConfigureBefore({ org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration.class, AsyncLoadBalancerAutoConfiguration.class }) @ConditionalOnClass(RestTemplate.class) +@ConditionalOnProperty(value = "spring.cloud.loadbalancer.enabled", havingValue = "true", matchIfMissing = true) public class BlockingLoadBalancerClientAutoConfiguration { @Bean diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerCacheAutoConfiguration.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerCacheAutoConfiguration.java index bb2e0d2d..324a8062 100644 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerCacheAutoConfiguration.java +++ b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerCacheAutoConfiguration.java @@ -25,6 +25,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.AllNestedConditions; import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -43,9 +44,9 @@ import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; /** - * An AutoConfiguration that automatically enables caching when when Spring Boot, and - * Spring Framework Cache support are present. If Caffeine is present in the classpath, it - * will be used for loadbalancer caching. If not, a default cache will be used. + * An AutoConfiguration that automatically enables caching when Spring Boot, and Spring + * Framework Cache support are present. If Caffeine is present in the classpath, it will + * be used for loadbalancer caching. If not, a default cache will be used. * * @author Olga Maciaszek-Sharma * @since 2.2.0 @@ -57,8 +58,8 @@ import org.springframework.context.annotation.Configuration; @Configuration(proxyBeanMethods = false) @ConditionalOnClass({ CacheManager.class, CacheAutoConfiguration.class }) @AutoConfigureAfter(CacheAutoConfiguration.class) -@ConditionalOnProperty(value = "spring.cloud.loadbalancer.cache.enabled", matchIfMissing = true) @EnableConfigurationProperties(LoadBalancerCacheProperties.class) +@Conditional(LoadBalancerCacheAutoConfiguration.OnLoadBalancerCachingEnabledCondition.class) public class LoadBalancerCacheAutoConfiguration { @Configuration(proxyBeanMethods = false) @@ -130,4 +131,22 @@ public class LoadBalancerCacheAutoConfiguration { } + static final class OnLoadBalancerCachingEnabledCondition extends AllNestedConditions { + + OnLoadBalancerCachingEnabledCondition() { + super(ConfigurationPhase.REGISTER_BEAN); + } + + @ConditionalOnProperty(value = "spring.cloud.loadbalancer.enabled", havingValue = "true", matchIfMissing = true) + static class LoadBalancerEnabled { + + } + + @ConditionalOnProperty(value = "spring.cloud.loadbalancer.cache.enabled", matchIfMissing = true) + static class LoadBalancerCacheEnabled { + + } + + } + } diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/config/BlockingLoadBalancerClientAutoConfigurationTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/config/BlockingLoadBalancerClientAutoConfigurationTests.java index c2d2ea3f..f0d7769e 100644 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/config/BlockingLoadBalancerClientAutoConfigurationTests.java +++ b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/config/BlockingLoadBalancerClientAutoConfigurationTests.java @@ -53,4 +53,12 @@ class BlockingLoadBalancerClientAutoConfigurationTests { }); } + @Test + void shouldNotFailOnRetryFactoryWhenLoadBalancingDisabled() { + applicationContextRunner.withPropertyValues("spring.cloud.loadbalancer.enabled=false").run(context -> { + assertThat(context).doesNotHaveBean(BlockingLoadBalancerClient.class); + assertThat(context).doesNotHaveBean(LoadBalancedRetryFactory.class); + }); + } + } diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/config/LoadBalancerCacheAutoConfigurationTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/config/LoadBalancerCacheAutoConfigurationTests.java index 12066f80..dbcf9f00 100644 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/config/LoadBalancerCacheAutoConfigurationTests.java +++ b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/config/LoadBalancerCacheAutoConfigurationTests.java @@ -171,6 +171,16 @@ class LoadBalancerCacheAutoConfigurationTests { }); } + @Test + void shouldNotInstantiateDefaultLoadBalancerCacheIfLoadBalancingDisabled() { + noCaffeineRunner().withPropertyValues("spring.cloud.loadbalancer.enabled=false") + .withUserConfiguration(TestConfiguration.class).run(context -> { + assertThat(context.getBeansOfType(CacheManager.class)).hasSize(1); + assertThat(context.getBean("cacheManager")).isInstanceOf(ConcurrentMapCacheManager.class); + assertThat(((CacheManager) context.getBean("cacheManager")).getCacheNames()).isEmpty(); + }); + } + private ApplicationContextRunner baseApplicationRunner() { return new ApplicationContextRunner().withConfiguration( AutoConfigurations.of(CacheAutoConfiguration.class, LoadBalancerCacheAutoConfiguration.class));