Я создал класс 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
Spring Retry использует AOP, внутренние вызовы (от getValue(int)
к getValue(ClassTest, int)
) не будут проходить через прокси.
Вы должны поместить @Retryable
в метод, который вызывается извне, чтобы прокси мог перехватить вызов и применить логику повтора.
Об аналогичной проблеме сообщается в https://github.com/spring-projects/spring-retry/issues/75
Итак, @EnableRetry(proxyTargetClass=true)
работает, поскольку теперь он может найти метод восстановления в классе реализации.
Привет, спасибо, моя попытка работает. Но я получаю
Cannot locate recovery method;
как исключение. Я пробовал сменить имя моего рекавери Mehod на getValue (исключение, целое число). Удалив аргумент ClassTest, чтобы он мог соответствовать повторяемому методу getValue (число). Все еще не работает.