How can I make spring @retryable configurable?

后端 未结 5 1723
误落风尘
误落风尘 2021-02-13 05:46

I have this piece of code

@Retryable(maxAttempts = 3, stateful = true, include = ServiceUnavailableException.class,
        exclude = URISyntaxException.class, b         


        
相关标签:
5条回答
  • 2021-02-13 05:59

    You can use RetryTemplate bean instead of @Retryable annotation like this:

    @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 execute method of this template:

    @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);
    }
    
    0 讨论(0)
  • 2021-02-13 06:03

    with the release of Spring-retry version 1.2, it's possible. @Retryable can be configured using 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

    0 讨论(0)
  • 2021-02-13 06:03

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

    @Retryable(maxAttemptsExpression = "#{${my.max.attempts:10}}")
    public void myRetryableMethod() {
        // ...
    }
    
    0 讨论(0)
  • 2021-02-13 06:10

    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.

    See this answer for 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.test is the method you want to apply retries to.

    0 讨论(0)
  • 2021-02-13 06:15

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

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

    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 {
    
    0 讨论(0)
提交回复
热议问题