Skip to content

Commit ffeaedc

Browse files
committed
spring-projectsGH-293: Fix Bean Resolver for CBreaker Expressions
Resolves spring-projects#293 **cherry-pick to 1.3.x**
1 parent b577e29 commit ffeaedc

File tree

2 files changed

+55
-5
lines changed

2 files changed

+55
-5
lines changed

src/main/java/org/springframework/retry/annotation/AnnotationAwareRetryOperationsInterceptor.java

+23-5
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@
6262
import org.springframework.retry.support.RetryTemplate;
6363
import org.springframework.util.ConcurrentReferenceHashMap;
6464
import org.springframework.util.ReflectionUtils;
65-
import org.springframework.util.ReflectionUtils.MethodCallback;
6665
import org.springframework.util.StringUtils;
6766

6867
/**
@@ -251,8 +250,15 @@ private MethodInterceptor getStatefulInterceptor(Object target, Method method, R
251250

252251
private long getOpenTimeout(CircuitBreaker circuit) {
253252
if (StringUtils.hasText(circuit.openTimeoutExpression())) {
254-
Long value = PARSER.parseExpression(resolve(circuit.openTimeoutExpression()), PARSER_CONTEXT)
255-
.getValue(Long.class);
253+
Long value = null;
254+
if (isTemplate(circuit.openTimeoutExpression())) {
255+
value = PARSER.parseExpression(resolve(circuit.openTimeoutExpression()), PARSER_CONTEXT)
256+
.getValue(this.evaluationContext, Long.class);
257+
}
258+
else {
259+
value = PARSER.parseExpression(resolve(circuit.openTimeoutExpression()))
260+
.getValue(this.evaluationContext, Long.class);
261+
}
256262
if (value != null) {
257263
return value;
258264
}
@@ -262,15 +268,27 @@ private long getOpenTimeout(CircuitBreaker circuit) {
262268

263269
private long getResetTimeout(CircuitBreaker circuit) {
264270
if (StringUtils.hasText(circuit.resetTimeoutExpression())) {
265-
Long value = PARSER.parseExpression(resolve(circuit.resetTimeoutExpression()), PARSER_CONTEXT)
266-
.getValue(Long.class);
271+
Long value = null;
272+
if (isTemplate(circuit.openTimeoutExpression())) {
273+
value = PARSER.parseExpression(resolve(circuit.resetTimeoutExpression()), PARSER_CONTEXT)
274+
.getValue(this.evaluationContext, Long.class);
275+
}
276+
else {
277+
value = PARSER.parseExpression(resolve(circuit.resetTimeoutExpression()))
278+
.getValue(this.evaluationContext, Long.class);
279+
}
267280
if (value != null) {
268281
return value;
269282
}
270283
}
271284
return circuit.resetTimeout();
272285
}
273286

287+
private boolean isTemplate(String expression) {
288+
return expression.contains(PARSER_CONTEXT.getExpressionPrefix())
289+
&& expression.contains(PARSER_CONTEXT.getExpressionSuffix());
290+
}
291+
274292
private RetryTemplate createTemplate(String[] listenersBeanNames) {
275293
RetryTemplate template = new RetryTemplate();
276294
if (listenersBeanNames.length > 0) {

src/test/java/org/springframework/retry/annotation/CircuitBreakerTests.java

+32
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ public void vanilla() throws Exception {
7979
assertThat(service.getCount()).isEqualTo(3);
8080
service.expressionService();
8181
assertThat(service.getCount()).isEqualTo(4);
82+
service.expressionService2();
83+
assertThat(service.getCount()).isEqualTo(5);
8284
Advised advised = (Advised) service;
8385
Advisor advisor = advised.getAdvisors()[0];
8486
Map<?, ?> delegates = (Map<?, ?>) new DirectFieldAccessor(advisor).getPropertyValue("advice.delegates");
@@ -92,6 +94,12 @@ public void vanilla() throws Exception {
9294
assertThat(accessor.getPropertyValue("retryOperations.retryPolicy.resetTimeout")).isEqualTo(20000L);
9395
assertThat(accessor.getPropertyValue("retryOperations.retryPolicy.delegate.expression.expression"))
9496
.isEqualTo("#root instanceof RuntimeExpression");
97+
98+
interceptor = (MethodInterceptor) methodMap.get(Service.class.getDeclaredMethod("expressionService2"));
99+
accessor = new DirectFieldAccessor(interceptor);
100+
assertThat(accessor.getPropertyValue("retryOperations.retryPolicy.delegate.maxAttempts")).isEqualTo(10);
101+
assertThat(accessor.getPropertyValue("retryOperations.retryPolicy.openTimeout")).isEqualTo(10000L);
102+
assertThat(accessor.getPropertyValue("retryOperations.retryPolicy.resetTimeout")).isEqualTo(20000L);
95103
context.close();
96104
}
97105

@@ -104,6 +112,21 @@ public Service service() {
104112
return new ServiceImpl();
105113
}
106114

115+
@Bean
116+
Configs configs() {
117+
return new Configs();
118+
}
119+
120+
}
121+
122+
public static class Configs {
123+
124+
public int maxAttempts = 10;
125+
126+
public long openTimeout = 10000;
127+
128+
public long resetTimeout = 20000;
129+
107130
}
108131

109132
interface Service {
@@ -112,6 +135,8 @@ interface Service {
112135

113136
void expressionService();
114137

138+
void expressionService2();
139+
115140
int getCount();
116141

117142
RetryContext getContext();
@@ -141,6 +166,13 @@ public void expressionService() {
141166
this.count++;
142167
}
143168

169+
@Override
170+
@CircuitBreaker(maxAttemptsExpression = "@configs.maxAttempts", openTimeoutExpression = "@configs.openTimeout",
171+
resetTimeoutExpression = "@configs.resetTimeout")
172+
public void expressionService2() {
173+
this.count++;
174+
}
175+
144176
@Override
145177
public RetryContext getContext() {
146178
return this.context;

0 commit comments

Comments
 (0)