Java 如何使 spring @retryable 可配置?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38088449/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 20:00:55  来源:igfitidea点击:

How can I make spring @retryable configurable?

javaspringspring-retry

提问by Sabarish

I have this piece of code

我有这段代码

@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 {

//some implementation here }

//这里有一些实现 }

Is there a way I can make the maxAttempts , delay and multiplier configurable using @Value? Or is there any other approach to make such fields inside annotations configurable?

有没有办法可以使用@Value 使 maxAttempts 、延迟和乘数配置?或者是否有其他方法可以使注释中的此类字段可配置?

采纳答案by Gary Russell

It's not currently possible; to wire in properties, the annotation would have to be changed to take String values and the annotation bean post-processor would have to resolve placeholders and/or SpEL expressions.

目前不可能;要连接属性,必须将注释更改为采用字符串值,并且注释 bean 后处理器必须解析占位符和/或 SpEL 表达式。

See this answerfor an alternative, but it can't currently be done via the annotation.

请参阅此答案以获取替代方法,但目前无法通过注释完成。

EDIT

编辑

<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>

Where EchoService.testis the method you want to apply retries to.

EchoService.test您要应用重试的方法在哪里。

回答by Sean Liang

You can use RetryTemplatebean instead of @Retryableannotation like this:

您可以使用RetryTemplatebean 而不是这样的@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;
}

And then use the executemethod of this 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);
}

回答by Satish

with the release of Spring-retry version 1.2, it's possible. @Retryable can be configured using SPEL.

随着 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
}

For more details refer: https://github.com/spring-projects/spring-retry/blob/master/README.md

更多详情请参考:https: //github.com/spring-projects/spring-retry/blob/master/README.md

回答by florbonansea

As it is explained here: https://stackoverflow.com/a/43144064

正如这里所解释的:https: //stackoverflow.com/a/43144064

Version 1.2 introduces the ability to use expressions for certain properties.

1.2 版引入了对某些属性使用表达式的能力。

So you need something like this:

所以你需要这样的东西:

@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 {

回答by whistling_marmot

If you want to supply a default, and then optionally override it in your application.properties file:

如果你想提供一个默认值,然后有选择地在你的 application.properties 文件中覆盖它:

@Retryable(maxAttemptsExpression = "#{${my.max.attempts:10}}")
public void myRetryableMethod() {
    // ...
}