可重试注释在 spring 批处理应用程序中不起作用

Retryable annotation is not working in spring batch application

这是我的 class 我调用一项服务的地方。 这是我绑定的代码

我也在 class 级别启用了重试。 我是否需要做任何其他事情才能使这项工作..

这是我的生产 spring 应用程序。上面的应用程序正是我在本地尝试 运行 的地方。

@Retryable(maxAttempts=2 ,value=NotFoundException.class,backoff = @Backoff(delay = 10000,multiplier=2))
private boolean extractVesselDetailsFromSOL(String imoNumber) {
    try{
        Entity result = nameMatcherRestClient.getEntity(VESSEL_PREFIX + imoNumber);
        if (result != null) {
            addVesselDetailsToMap(result, imoNumber);
            addAssociateDetailsToMap(result, imoNumber);
        }
    }catch(NotFoundException e){
        LOGGER.error("Exception in extractVesselDetailsFromSOL :: "+e.getMessage());
        LOGGER.error("Exception in extractVesselDetailsFromSOL :: "+Count++);
        System.out.println("NameMatcher --> " + Count++);
        return false;
    }
    return true;
}

这是我调用上述方法的地方

private boolean getVesselDetails(String imoNumber){
    return ((!vesselDetailsFromSol.containsKey(imoNumber)) && (!extractVesselDetailsFromSOL(imoNumber)));
}

看到您更新的问题,我想我知道问题出在哪里:您正在从同一个 bean 中调用 extractVesselDetailsFromSOL(这是一个私有方法)。需要从不同的 bean 调用 @Retryable 方法,以便 AOP(重试)功能可以启动。您应该将代码重构为:

public class SomeBean {

    @Autowired
    private SomeOtherBean someOtherBean;

    public someOperation() {
        ...
        someOtherBean.extractVesselDetailsFromSOL(xxx);
    }
}

public class SomeOtherBean {

    @Retryable(maxAttempts=2 ,value=NotFoundException.class,backoff = @Backoff(delay = 10000,multiplier=2))
    public boolean extractVesselDetailsFromSOL(String imoNumber) {
        try{
            Entity result = nameMatcherRestClient.getEntity(VESSEL_PREFIX + imoNumber);
            if (result != null) {
                addVesselDetailsToMap(result, imoNumber);
                addAssociateDetailsToMap(result, imoNumber);
            }
        }catch(NotFoundException e){
            LOGGER.error("Exception in extractVesselDetailsFromSOL :: "+e.getMessage());
            LOGGER.error("Exception in extractVesselDetailsFromSOL :: "+Count++);
            System.out.println("NameMatcher --> " + Count++);
            return false;
        }
        return true;
    }
}

Reference:

Due to the proxy-based nature of Spring’s AOP framework, calls within the target object are by definition not intercepted. For JDK proxies, only public interface method calls on the proxy can be intercepted. With CGLIB, public and protected method calls on the proxy will be intercepted, and even package-visible methods if necessary. However, common interactions through proxies should always be designed through public signatures.

Note that pointcut definitions are generally matched against any intercepted method. If a pointcut is strictly meant to be public-only, even in a CGLIB proxy scenario with potential non-public interactions through proxies, it needs to be defined accordingly.

If your interception needs include method calls or even constructors within the target class, consider the use of Spring-driven native AspectJ weaving instead of Spring’s proxy-based AOP framework. This constitutes a different mode of AOP usage with different characteristics, so be sure to make yourself familiar with weaving first before making a decision.

有人和你有同样的问题asked on Github,解决方案就是我在上面展示的:使该功能从一个 bean 可用并从另一个 bean 调用。