Как я могу сделать пружину @retryable настраиваемой?

У меня есть этот кусок кода

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

// некоторая реализация здесь}

Есть ли способ сделать maxAttempts, задержку и множитель настраиваемыми с помощью @Value? Или есть какой-то другой способ сделать такие поля внутри аннотаций настраиваемыми?

Ответы на вопрос(5)

роить с помощью 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

https://stackoverflow.com/a/43144064

В версии 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 {
 cegas16 мая 2018 г., 10:26
Я могу ошибаться, но по крайней мере для меня это работает без#{}, то есть,"${your.delay}" выбран (конечно, вам нужно сначала определить его в файле свойств).

а затем при необходимости переопределить его в файле application.properties:

@Retryable(maxAttemptsExpression = "#{${my.max.attempts:10}}")
public void myRetryableMethod() {
    // ...
}
Решение Вопроса

для привязки к свойствам необходимо изменить аннотацию, чтобы она принимала значения String, а постпроцессору объекта обработки аннотаций пришлось бы разрешать заполнители и / или выражения SpEL.

Увидетьэтот ответ для альтернативы, но в настоящее время это не может быть сделано с помощью аннотации.

РЕДАКТИРОВАТЬ

<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 метод, к которому вы хотите применить повторные попытки.

 Gary Russell29 июн. 2016 г., 20:02
Я добавил пример, используя конфигурацию XML.
 Sabarish29 июн. 2016 г., 16:58
Если вы не возражаете, не могли бы вы также привести пример с использованием RetryOperationsInterceptor?

Ты можешь использоватьRetryTemplate боб вместо@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);
}

Ваш ответ на вопрос