diff --git a/src/main/java/org/springframework/retry/annotation/AnnotationAwareRetryOperationsInterceptor.java b/src/main/java/org/springframework/retry/annotation/AnnotationAwareRetryOperationsInterceptor.java index 3782f86b..74585b09 100644 --- a/src/main/java/org/springframework/retry/annotation/AnnotationAwareRetryOperationsInterceptor.java +++ b/src/main/java/org/springframework/retry/annotation/AnnotationAwareRetryOperationsInterceptor.java @@ -62,7 +62,6 @@ import org.springframework.retry.support.RetryTemplate; import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.ReflectionUtils; -import org.springframework.util.ReflectionUtils.MethodCallback; import org.springframework.util.StringUtils; /** @@ -251,8 +250,15 @@ private MethodInterceptor getStatefulInterceptor(Object target, Method method, R private long getOpenTimeout(CircuitBreaker circuit) { if (StringUtils.hasText(circuit.openTimeoutExpression())) { - Long value = PARSER.parseExpression(resolve(circuit.openTimeoutExpression()), PARSER_CONTEXT) - .getValue(Long.class); + Long value = null; + if (isTemplate(circuit.openTimeoutExpression())) { + value = PARSER.parseExpression(resolve(circuit.openTimeoutExpression()), PARSER_CONTEXT) + .getValue(this.evaluationContext, Long.class); + } + else { + value = PARSER.parseExpression(resolve(circuit.openTimeoutExpression())) + .getValue(this.evaluationContext, Long.class); + } if (value != null) { return value; } @@ -262,8 +268,15 @@ private long getOpenTimeout(CircuitBreaker circuit) { private long getResetTimeout(CircuitBreaker circuit) { if (StringUtils.hasText(circuit.resetTimeoutExpression())) { - Long value = PARSER.parseExpression(resolve(circuit.resetTimeoutExpression()), PARSER_CONTEXT) - .getValue(Long.class); + Long value = null; + if (isTemplate(circuit.openTimeoutExpression())) { + value = PARSER.parseExpression(resolve(circuit.resetTimeoutExpression()), PARSER_CONTEXT) + .getValue(this.evaluationContext, Long.class); + } + else { + value = PARSER.parseExpression(resolve(circuit.resetTimeoutExpression())) + .getValue(this.evaluationContext, Long.class); + } if (value != null) { return value; } @@ -271,6 +284,11 @@ private long getResetTimeout(CircuitBreaker circuit) { return circuit.resetTimeout(); } + private boolean isTemplate(String expression) { + return expression.contains(PARSER_CONTEXT.getExpressionPrefix()) + && expression.contains(PARSER_CONTEXT.getExpressionSuffix()); + } + private RetryTemplate createTemplate(String[] listenersBeanNames) { RetryTemplate template = new RetryTemplate(); if (listenersBeanNames.length > 0) { diff --git a/src/test/java/org/springframework/retry/annotation/CircuitBreakerTests.java b/src/test/java/org/springframework/retry/annotation/CircuitBreakerTests.java index 7df7ba8b..3576342f 100644 --- a/src/test/java/org/springframework/retry/annotation/CircuitBreakerTests.java +++ b/src/test/java/org/springframework/retry/annotation/CircuitBreakerTests.java @@ -79,6 +79,8 @@ public void vanilla() throws Exception { assertThat(service.getCount()).isEqualTo(3); service.expressionService(); assertThat(service.getCount()).isEqualTo(4); + service.expressionService2(); + assertThat(service.getCount()).isEqualTo(5); Advised advised = (Advised) service; Advisor advisor = advised.getAdvisors()[0]; Map delegates = (Map) new DirectFieldAccessor(advisor).getPropertyValue("advice.delegates"); @@ -92,6 +94,12 @@ public void vanilla() throws Exception { assertThat(accessor.getPropertyValue("retryOperations.retryPolicy.resetTimeout")).isEqualTo(20000L); assertThat(accessor.getPropertyValue("retryOperations.retryPolicy.delegate.expression.expression")) .isEqualTo("#root instanceof RuntimeExpression"); + + interceptor = (MethodInterceptor) methodMap.get(Service.class.getDeclaredMethod("expressionService2")); + accessor = new DirectFieldAccessor(interceptor); + assertThat(accessor.getPropertyValue("retryOperations.retryPolicy.delegate.maxAttempts")).isEqualTo(10); + assertThat(accessor.getPropertyValue("retryOperations.retryPolicy.openTimeout")).isEqualTo(10000L); + assertThat(accessor.getPropertyValue("retryOperations.retryPolicy.resetTimeout")).isEqualTo(20000L); context.close(); } @@ -104,6 +112,21 @@ public Service service() { return new ServiceImpl(); } + @Bean + Configs configs() { + return new Configs(); + } + + } + + public static class Configs { + + public int maxAttempts = 10; + + public long openTimeout = 10000; + + public long resetTimeout = 20000; + } interface Service { @@ -112,6 +135,8 @@ interface Service { void expressionService(); + void expressionService2(); + int getCount(); RetryContext getContext(); @@ -141,6 +166,13 @@ public void expressionService() { this.count++; } + @Override + @CircuitBreaker(maxAttemptsExpression = "@configs.maxAttempts", openTimeoutExpression = "@configs.openTimeout", + resetTimeoutExpression = "@configs.resetTimeout") + public void expressionService2() { + this.count++; + } + @Override public RetryContext getContext() { return this.context;