Spring Retry不适用于第二级方法

Sub*_*a M 8 java spring

@Retryable似乎没有在第二级方法上工作,sphRemoteCall如下所示.我看到创建了一个代理,但它永远不会在失败时重试.

一旦我转到@Retryable第一级方法 getSubscriberAccount,它就开始工作了.

示例如下:

@Service
public class SphIptvClient extends WebServiceGatewaySupport {
    //Works over here
    @Retryable(maxAttempts=3, backoff=@Backoff(delay=100))
    public GetSubscriberAccountResponse getSubscriberAccount(String loginTocken, String billingServId) {

        GetSubscriberAccountResponse response = (GetSubscriberAccountResponse) sphRemoteCall(sphIptvEndPoint, getSubAcc, "xxxxx");
        return response;
    }

    /*
     * Retryable is not working on the 2nd level methods in the bean. 
     * It works only with methods which are called directly from outside
     * if there is 2nd level method, like this, Retryable is not working.
     */
    //@Retryable
    private Object sphRemoteCall(String uri, Object requestPayload, String soapAction) {
        log.debug("Calling the sph for uri:{} and soapAction:{}", uri, soapAction);
        return getWebServiceTemplate().marshalSendAndReceive(uri, requestPayload, new SoapActionCallback(soapAction));
    }
}

@Configuration
@EnableRetry
public class SphClientConfig {
    @Bean
    public SphIptvClient sphIptvClient() {
        SphIptvClient client = new SphIptvClient();
        return client;
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*son 9

所以这是一个非常晚的答案,但由于我刚刚来到这里并遇到了同样的问题(再次,在几年前与交易搏斗之后)我将提供一个更充实的解决方案,希望有人会发现它有用。足以说@M。Deinum的诊断是正确的。

在此处输入图片说明

在此处输入图片说明

在上述情况下,解释一下理解 AOP 代理,任何SphIptvClient自动装配的地方都将被引用到@EnableRetry处理Spring Retry 将创建的代理:

@EnableRetry注释为@Retryablebean创建代理” -声明式重试 - Spring Retry

一旦getSubscriberAccount被调用并且执行已经通过代理并进入@Service对象的实例,就不会知道对代理的引用。结果sphRemoteCall被称为好像根本没有@Retryable

您可以通过以允许getSubscriberAccount调用 proxy-ed的方式改组代码来使用框架sphRemoteCall,这需要新的接口和类实现。

例如:

public interface SphWebService {
   Object sphRemoteCall(String uri, Object requestPayload, String soapAction);
}

@Component
public class SphWebServiceImpl implements SphWebService {
   @Retryable
   public Object sphRemoteCall(String uri, Object requestPayload, String soapAction) {
       log.debug("Calling the sph for uri:{} and soapAction:{}", uri, soapAction);
       return getWebServiceTemplate().marshalSendAndReceive(uri, requestPayload, new SoapActionCallback(soapAction));
   }
}

@Service
public class SphIptvClient extends WebServiceGatewaySupport {

   @Autowired
   SphWebService sphWebService;

   @Retryable(maxAttempts=3, backoff=@Backoff(delay=100))
   public GetSubscriberAccountResponse getSubscriberAccount(String loginTocken, String billingServId) {
       GetSubscriberAccountResponse response = (GetSubscriberAccountResponse) this.sphWebService.sphRemoteCall(sphIptvEndPoint, getSubAcc, "xxxxx");
       return response;
   }
}

@Configuration
@EnableRetry
public class SphClientConfig {
   // the @Bean method was unnecessary and may cause confusion. 
   // @Service was already instantiating SphIptvClient behind the scenes.
}
Run Code Online (Sandbox Code Playgroud)