Skip to content

Commit 1129178

Browse files
committed
Refine circuit breaker builder configuration
Signed-off-by: hutiefang76 <137664623+hutiefang76@users.noreply.github.com>
1 parent e830579 commit 1129178

4 files changed

Lines changed: 102 additions & 33 deletions

File tree

spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignAutoConfiguration.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
import org.springframework.aot.hint.RuntimeHintsRegistrar;
3838
import org.springframework.aot.hint.TypeReference;
3939
import org.springframework.beans.factory.annotation.Autowired;
40-
import org.springframework.beans.factory.annotation.Value;
4140
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
4241
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
4342
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -86,7 +85,7 @@
8685
@Configuration(proxyBeanMethods = false)
8786
@ConditionalOnClass(Feign.class)
8887
@EnableConfigurationProperties({ FeignClientProperties.class, FeignHttpClientProperties.class,
89-
FeignEncoderProperties.class, FeignOAuth2Properties.class })
88+
FeignEncoderProperties.class, FeignOAuth2Properties.class, FeignCircuitBreakerProperties.class })
9089
public class FeignAutoConfiguration {
9190

9291
private static final Log LOG = LogFactory.getLog(FeignAutoConfiguration.class);
@@ -189,10 +188,10 @@ public CircuitBreakerNameResolver alphanumericCircuitBreakerNameResolver() {
189188
@ConditionalOnMissingBean
190189
@ConditionalOnBean(CircuitBreakerFactory.class)
191190
public Targeter circuitBreakerFeignTargeter(CircuitBreakerFactory circuitBreakerFactory,
192-
@Value("${spring.cloud.openfeign.circuitbreaker.group.enabled:false}") boolean circuitBreakerGroupEnabled,
191+
FeignCircuitBreakerProperties circuitBreakerProperties,
193192
CircuitBreakerNameResolver circuitBreakerNameResolver) {
194-
return new FeignCircuitBreakerTargeter(circuitBreakerFactory, circuitBreakerGroupEnabled,
195-
circuitBreakerNameResolver);
193+
return new FeignCircuitBreakerTargeter(circuitBreakerFactory,
194+
circuitBreakerProperties.getGroup().isEnabled(), circuitBreakerNameResolver);
196195
}
197196

198197
static class DefaultCircuitBreakerNameResolver implements CircuitBreakerNameResolver {
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright 2013-present 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.openfeign;
18+
19+
import org.springframework.boot.context.properties.ConfigurationProperties;
20+
21+
/**
22+
* Configuration properties for Feign circuit breaker support.
23+
*/
24+
@ConfigurationProperties("spring.cloud.openfeign.circuitbreaker")
25+
public class FeignCircuitBreakerProperties {
26+
27+
private Group group = new Group();
28+
29+
private AlphanumericIds alphanumericIds = new AlphanumericIds();
30+
31+
public Group getGroup() {
32+
return group;
33+
}
34+
35+
public void setGroup(Group group) {
36+
this.group = group;
37+
}
38+
39+
public AlphanumericIds getAlphanumericIds() {
40+
return alphanumericIds;
41+
}
42+
43+
public void setAlphanumericIds(AlphanumericIds alphanumericIds) {
44+
this.alphanumericIds = alphanumericIds;
45+
}
46+
47+
public static class Group {
48+
49+
private boolean enabled;
50+
51+
public boolean isEnabled() {
52+
return enabled;
53+
}
54+
55+
public void setEnabled(boolean enabled) {
56+
this.enabled = enabled;
57+
}
58+
59+
}
60+
61+
public static class AlphanumericIds {
62+
63+
private boolean enabled = true;
64+
65+
public boolean isEnabled() {
66+
return enabled;
67+
}
68+
69+
public void setEnabled(boolean enabled) {
70+
this.enabled = enabled;
71+
}
72+
73+
}
74+
75+
}

spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientsConfiguration.java

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636

3737
import org.springframework.beans.factory.ObjectProvider;
3838
import org.springframework.beans.factory.annotation.Autowired;
39-
import org.springframework.beans.factory.annotation.Value;
4039
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
4140
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
4241
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -240,46 +239,34 @@ public Feign.Builder feignBuilder(Retryer retryer) {
240239
@ConditionalOnProperty("spring.cloud.openfeign.circuitbreaker.enabled")
241240
protected static class CircuitBreakerPresentFeignBuilderConfiguration {
242241

243-
@Autowired
244-
private CircuitBreakerFactory circuitBreakerFactory;
245-
246-
@Value("${spring.cloud.openfeign.circuitbreaker.group.enabled:false}")
247-
private boolean circuitBreakerGroupEnabled;
248-
249-
@Value("${spring.cloud.openfeign.circuitbreaker.alphanumeric-ids.enabled:true}")
250-
private boolean alphanumericIdsEnabled;
251-
252-
@Autowired
253-
private ObjectProvider<CircuitBreakerNameResolver> circuitBreakerNameResolver;
254-
255242
@Bean
256243
@Scope("prototype")
257244
@ConditionalOnMissingBean({ Feign.Builder.class, CircuitBreakerFactory.class })
258245
public Feign.Builder defaultFeignBuilder(Retryer retryer) {
259246
return Feign.builder().retryer(retryer);
260247
}
261248

249+
public Feign.Builder circuitBreakerFeignBuilder() {
250+
return FeignCircuitBreaker.builder();
251+
}
252+
262253
@Bean
263254
@Scope("prototype")
264255
@ConditionalOnMissingBean
265256
@ConditionalOnBean(CircuitBreakerFactory.class)
266-
public Feign.Builder circuitBreakerFeignBuilder() {
267-
return circuitBreakerFeignBuilder(circuitBreakerFactory, circuitBreakerGroupEnabled, alphanumericIdsEnabled,
268-
circuitBreakerNameResolver);
269-
}
270-
271257
public Feign.Builder circuitBreakerFeignBuilder(CircuitBreakerFactory circuitBreakerFactory,
272-
boolean circuitBreakerGroupEnabled, boolean alphanumericIdsEnabled,
258+
FeignCircuitBreakerProperties circuitBreakerProperties,
273259
ObjectProvider<CircuitBreakerNameResolver> circuitBreakerNameResolver) {
274260
return FeignCircuitBreaker.builder()
275261
.circuitBreakerFactory(circuitBreakerFactory)
276-
.circuitBreakerGroupEnabled(circuitBreakerGroupEnabled)
262+
.circuitBreakerGroupEnabled(circuitBreakerProperties.getGroup().isEnabled())
277263
.circuitBreakerNameResolver(circuitBreakerNameResolver
278-
.getIfAvailable(() -> defaultCircuitBreakerNameResolver(alphanumericIdsEnabled)));
264+
.getIfAvailable(() -> defaultCircuitBreakerNameResolver(circuitBreakerProperties)));
279265
}
280266

281-
private CircuitBreakerNameResolver defaultCircuitBreakerNameResolver(boolean alphanumericIdsEnabled) {
282-
if (alphanumericIdsEnabled) {
267+
private CircuitBreakerNameResolver defaultCircuitBreakerNameResolver(
268+
FeignCircuitBreakerProperties circuitBreakerProperties) {
269+
if (circuitBreakerProperties.getAlphanumericIds().isEnabled()) {
283270
return new AlphanumericCircuitBreakerNameResolver();
284271
}
285272
return new DefaultCircuitBreakerNameResolver();

spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/FeignAutoConfigurationTests.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.assertj.core.api.Condition;
2828
import org.junit.jupiter.api.Test;
2929

30+
import org.springframework.beans.factory.ObjectProvider;
3031
import org.springframework.boot.autoconfigure.AutoConfigurations;
3132
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
3233
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
@@ -36,6 +37,7 @@
3637
import org.springframework.cloud.openfeign.FeignAutoConfiguration.CircuitBreakerPresentFeignTargeterConfiguration.DefaultCircuitBreakerNameResolver;
3738
import org.springframework.cloud.openfeign.security.OAuth2AccessTokenInterceptor;
3839
import org.springframework.context.ConfigurableApplicationContext;
40+
import org.springframework.context.annotation.Bean;
3941
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
4042
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
4143
import org.springframework.test.util.ReflectionTestUtils;
@@ -104,11 +106,15 @@ void shouldInstantiateFeignCircuitBreakerTargeterWhenEnabledWithCustomCircuitBre
104106

105107
@Test
106108
void shouldKeepNoArgCircuitBreakerFeignBuilderSignature() throws NoSuchMethodException {
107-
Method method = FeignClientsConfiguration.CircuitBreakerPresentFeignBuilderConfiguration.class
109+
Method noArgMethod = FeignClientsConfiguration.CircuitBreakerPresentFeignBuilderConfiguration.class
108110
.getDeclaredMethod("circuitBreakerFeignBuilder");
111+
Method beanMethod = FeignClientsConfiguration.CircuitBreakerPresentFeignBuilderConfiguration.class
112+
.getDeclaredMethod("circuitBreakerFeignBuilder", CircuitBreakerFactory.class,
113+
FeignCircuitBreakerProperties.class, ObjectProvider.class);
109114

110-
assertThat(Modifier.isPublic(method.getModifiers())).isTrue();
111-
assertThat(method.getReturnType()).isEqualTo(Feign.Builder.class);
115+
assertThat(Modifier.isPublic(noArgMethod.getModifiers())).isTrue();
116+
assertThat(noArgMethod.getReturnType()).isEqualTo(Feign.Builder.class);
117+
assertThat(beanMethod.isAnnotationPresent(Bean.class)).isTrue();
112118
}
113119

114120
@Test
@@ -134,7 +140,8 @@ void shouldConfigureCircuitBreakerFeignBuilderWhenUsedDirectly() {
134140
@Test
135141
void shouldConfigureCircuitBreakerFeignBuilderWithoutNameResolverBean() throws NoSuchMethodException {
136142
CircuitBreakerFactory<?, ?> circuitBreakerFactory = mock(CircuitBreakerFactory.class);
137-
new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(FeignClientsConfiguration.class))
143+
new ApplicationContextRunner()
144+
.withConfiguration(AutoConfigurations.of(FeignAutoConfiguration.class, FeignClientsConfiguration.class))
138145
.withPropertyValues("spring.cloud.openfeign.circuitbreaker.enabled=true",
139146
"spring.cloud.openfeign.httpclient.hc5.enabled=false")
140147
.withBean(CircuitBreakerFactory.class, () -> circuitBreakerFactory)
@@ -160,7 +167,8 @@ void shouldConfigureCircuitBreakerFeignBuilderWithoutNameResolverBean() throws N
160167
void shouldConfigureDefaultCircuitBreakerFeignBuilderNameResolverWhenAlphanumericIdsDisabled()
161168
throws NoSuchMethodException {
162169
CircuitBreakerFactory<?, ?> circuitBreakerFactory = mock(CircuitBreakerFactory.class);
163-
new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(FeignClientsConfiguration.class))
170+
new ApplicationContextRunner()
171+
.withConfiguration(AutoConfigurations.of(FeignAutoConfiguration.class, FeignClientsConfiguration.class))
164172
.withPropertyValues("spring.cloud.openfeign.circuitbreaker.enabled=true",
165173
"spring.cloud.openfeign.circuitbreaker.alphanumeric-ids.enabled=false",
166174
"spring.cloud.openfeign.httpclient.hc5.enabled=false")

0 commit comments

Comments
 (0)