如何使 spring @retryable 可配置?
How can I make spring @retryable configurable?
我有这段代码
@Retryable(maxAttempts = 3, stateful = true, include = ServiceUnavailableException.class,
exclude = URISyntaxException.class, backoff = @Backoff(delay = 1000, multiplier = 2) )
public void testThatService(String serviceAccountId)
throws ServiceUnavailableException, URISyntaxException {
//这里有一些实现
}
有没有办法可以使用@Value 来配置 maxAttempts 、延迟和乘数?
或者是否有任何其他方法可以使注释中的此类字段可配置?
目前不可能;要连接属性,必须更改注释以采用字符串值,并且注释 bean post-处理器必须解析占位符 and/or SpEL 表达式。
请参阅 this answer 了解替代方案,但目前无法通过注释完成。
编辑
<bean id="retryAdvice" class="org.springframework.retry.interceptor.RetryOperationsInterceptor">
<property name="retryOperations">
<bean class="org.springframework.retry.support.RetryTemplate">
<property name="retryPolicy">
<bean class="org.springframework.retry.policy.SimpleRetryPolicy">
<property name="maxAttempts" value="${max.attempts}" />
</bean>
</property>
<property name="backOffPolicy">
<bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
<property name="initialInterval" value="${delay}" />
<property name="multiplier" value="${multiplier}" />
</bean>
</property>
</bean>
</property>
</bean>
<aop:config>
<aop:pointcut id="retries"
expression="execution(* org..EchoService.test(..))" />
<aop:advisor pointcut-ref="retries" advice-ref="retryAdvice"
order="-1" />
</aop:config>
其中 EchoService.test
是您要应用重试的方法。
您可以像这样使用 RetryTemplate
bean 而不是 @Retryable
注释:
@Value("${retry.max-attempts}")
private int maxAttempts;
@Value("${retry.delay}")
private long delay;
@Bean
public RetryTemplate retryTemplate() {
SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
retryPolicy.setMaxAttempts(maxAttempts);
FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
backOffPolicy.setBackOffPeriod(delay);
RetryTemplate template = new RetryTemplate();
template.setRetryPolicy(retryPolicy);
template.setBackOffPolicy(backOffPolicy);
return template;
}
然后使用这个模板的execute
方法:
@Autowired
private RetryTemplate retryTemplate;
public ResponseVo doSomething(final Object data) {
RetryCallback<ResponseVo, SomeException> retryCallback = new RetryCallback<ResponseVo, SomeException>() {
@Override
public ResponseVo doWithRetry(RetryContext context) throws SomeException {
// do the business
return responseVo;
}
};
return retryTemplate.execute(retryCallback);
}
随着 Spring-retry 1.2 版的发布,这是可能的。 @Retryable 可以使用 SPEL 配置。
@Retryable(
value = { SomeException.class,AnotherException.class },
maxAttemptsExpression = "#{@myBean.getMyProperties('retryCount')}",
backoff = @Backoff(delayExpression = "#{@myBean.getMyProperties('retryInitalInterval')}"))
public void doJob(){
//your code here
}
更多详情请参考:https://github.com/spring-projects/spring-retry/blob/master/README.md
正如这里所解释的那样:
1.2 版引入了对某些属性使用表达式的功能。
所以你需要这样的东西:
@Retryable(maxAttempts = 3, stateful = true, include = ServiceUnavailableException.class,
exclude = URISyntaxException.class, backoff = @Backoff(delayExpression = "#{${your.delay}}" , multiplier = 2) )
public void testThatService(String serviceAccountId)
throws ServiceUnavailableException, URISyntaxException {
如果您想提供一个默认值,然后有选择地在您的 application.properties 文件中覆盖它:
@Retryable(maxAttemptsExpression = "#{${my.max.attempts:10}}")
public void myRetryableMethod() {
// ...
}
我有这段代码
@Retryable(maxAttempts = 3, stateful = true, include = ServiceUnavailableException.class,
exclude = URISyntaxException.class, backoff = @Backoff(delay = 1000, multiplier = 2) )
public void testThatService(String serviceAccountId)
throws ServiceUnavailableException, URISyntaxException {
//这里有一些实现 }
有没有办法可以使用@Value 来配置 maxAttempts 、延迟和乘数? 或者是否有任何其他方法可以使注释中的此类字段可配置?
目前不可能;要连接属性,必须更改注释以采用字符串值,并且注释 bean post-处理器必须解析占位符 and/or SpEL 表达式。
请参阅 this answer 了解替代方案,但目前无法通过注释完成。
编辑
<bean id="retryAdvice" class="org.springframework.retry.interceptor.RetryOperationsInterceptor">
<property name="retryOperations">
<bean class="org.springframework.retry.support.RetryTemplate">
<property name="retryPolicy">
<bean class="org.springframework.retry.policy.SimpleRetryPolicy">
<property name="maxAttempts" value="${max.attempts}" />
</bean>
</property>
<property name="backOffPolicy">
<bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
<property name="initialInterval" value="${delay}" />
<property name="multiplier" value="${multiplier}" />
</bean>
</property>
</bean>
</property>
</bean>
<aop:config>
<aop:pointcut id="retries"
expression="execution(* org..EchoService.test(..))" />
<aop:advisor pointcut-ref="retries" advice-ref="retryAdvice"
order="-1" />
</aop:config>
其中 EchoService.test
是您要应用重试的方法。
您可以像这样使用 RetryTemplate
bean 而不是 @Retryable
注释:
@Value("${retry.max-attempts}")
private int maxAttempts;
@Value("${retry.delay}")
private long delay;
@Bean
public RetryTemplate retryTemplate() {
SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
retryPolicy.setMaxAttempts(maxAttempts);
FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
backOffPolicy.setBackOffPeriod(delay);
RetryTemplate template = new RetryTemplate();
template.setRetryPolicy(retryPolicy);
template.setBackOffPolicy(backOffPolicy);
return template;
}
然后使用这个模板的execute
方法:
@Autowired
private RetryTemplate retryTemplate;
public ResponseVo doSomething(final Object data) {
RetryCallback<ResponseVo, SomeException> retryCallback = new RetryCallback<ResponseVo, SomeException>() {
@Override
public ResponseVo doWithRetry(RetryContext context) throws SomeException {
// do the business
return responseVo;
}
};
return retryTemplate.execute(retryCallback);
}
随着 Spring-retry 1.2 版的发布,这是可能的。 @Retryable 可以使用 SPEL 配置。
@Retryable(
value = { SomeException.class,AnotherException.class },
maxAttemptsExpression = "#{@myBean.getMyProperties('retryCount')}",
backoff = @Backoff(delayExpression = "#{@myBean.getMyProperties('retryInitalInterval')}"))
public void doJob(){
//your code here
}
更多详情请参考:https://github.com/spring-projects/spring-retry/blob/master/README.md
正如这里所解释的那样:
1.2 版引入了对某些属性使用表达式的功能。
所以你需要这样的东西:
@Retryable(maxAttempts = 3, stateful = true, include = ServiceUnavailableException.class,
exclude = URISyntaxException.class, backoff = @Backoff(delayExpression = "#{${your.delay}}" , multiplier = 2) )
public void testThatService(String serviceAccountId)
throws ServiceUnavailableException, URISyntaxException {
如果您想提供一个默认值,然后有选择地在您的 application.properties 文件中覆盖它:
@Retryable(maxAttemptsExpression = "#{${my.max.attempts:10}}")
public void myRetryableMethod() {
// ...
}