Spring 4 - Spring retry 1.2.1.RELEASE @Recover не работает

Я создал класс adapterImpl, который будет повторять попытку метода с objA, но если он выдает исключение (жестко запрограммировано для выброса), он вызовет метод восстановления, который снова вызовет метод с objB.

Моя проблема - метод @Recover не вызывается. Я не уверен, что я здесь делаю не так.

Весенняя версия - 4.3.5.RELEASE

Spring retry - 1.2.1.RELEASE

Мой класс конфигурации -

@Configuration
@EnableRetry
public class ConfigClass {

@Bean
public ClassTest beanA(){
    ClassTest obj = new ClassTest();
    obj.setProp(5);
    return obj;
}

@Bean
public ClassTest beanB(){
    ClassTest obj = new ClassTest();
    obj.setProp(10);
    return obj;
}

@Bean("adapterImpl")
public AdapterInterfaceImpl adapter(){
    AdapterInterfaceImpl obj = new AdapterInterfaceImpl();
    return obj;
}
}

Мой класс AdapterInterfaceImpl -

public class AdapterInterfaceImpl implements AdapterInterface{

@Autowired
@Qualifier("beanA")
private ClassTest objA;

@Autowired
@Qualifier("beanB")
private ClassTest objB;


public ClassTest getObjA() {
    return objA;
}


public void setObjA(ClassTest objA) {
    this.objA = objA;
}


public ClassTest getObjB() {
    return objB;
}


public void setObjB(ClassTest objB) {
    this.objB = objB;
}


@Retryable(maxAttempts = 3, include = Exception.class, backoff = @Backoff(delay = 2000))
public int getValue(int val) throws Exception{
    System.out.println("obj A get Value");
    return getValue(objA,val);
}


public int getValue(ClassTest obj, int val) throws Exception{
    System.out.println("get Value");
    if (obj==objA){
        throw new Exception("This is msg");
    }
    return obj.methodA(val);
}

@Recover
public int getValue(Exception e, int val){
    System.out.println("Recover get Value");
    try{
        return getValue(objB,val);
    }catch(Exception e1){
        return 0;
    }           
}

Мой класс ClassTest -

public class ClassTest {
private int prop;

public int getProp() {
    return prop;
}

public void setProp(int prop) {
    this.prop = prop;
}

public int methodA(int x){
    return x+prop;
}

}

Мой класс с основным методом -

public class App 
{   
public static void main( String[] args )
{
    AbstractApplicationContext context = new 
    AnnotationConfigApplicationContext(ConfigClass.class);
    AdapterInterface adapter = (AdapterInterface) 
    context.getBean("adapterImpl");
    try {
        System.out.println(adapter.getValue(3));
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
}

Мой вывод не показывает никаких повторных попыток или восстановления -

 A get Value
 get Value
 obj A get Value
 get Value
 obj A get Value
 get Value
 org.springframework.retry.ExhaustedRetryException: Cannot locate recovery method; nested exception is java.lang.Exception: This is msg
0
0
1 879
2

Ответы 2

Spring Retry использует AOP, внутренние вызовы (от getValue(int) к getValue(ClassTest, int)) не будут проходить через прокси.

Вы должны поместить @Retryable в метод, который вызывается извне, чтобы прокси мог перехватить вызов и применить логику повтора.

Привет, спасибо, моя попытка работает. Но я получаю Cannot locate recovery method; как исключение. Я пробовал сменить имя моего рекавери Mehod на getValue (исключение, целое число). Удалив аргумент ClassTest, чтобы он мог соответствовать повторяемому методу getValue (число). Все еще не работает.

user93726 02.05.2018 06:11

Об аналогичной проблеме сообщается в https://github.com/spring-projects/spring-retry/issues/75

Итак, @EnableRetry(proxyTargetClass=true) работает, поскольку теперь он может найти метод восстановления в классе реализации.

Другие вопросы по теме