@Around切入点调用方法两次

Mic*_*ber 4 java aspectj spring-aop

有时我的API抛出异常,该服务器无法处理我的请求.我决定创建一个AOP方面,它将重新调用API调用.例如,5次,之后抛出异常,如果它仍然不起作用.

请看我的AOP课程.这不是一个完整的机构,但我希望你能够理解发生了什么:

@Aspect
public class RetryRequestExecutor {

    ....

    @Around("@annotation(com.test.RequestRetriable)")
    public Object retryApiRequest(ProceedingJoinPoint point) throws Throwable {
        int numAttempts = 0;
        ServiceException lastException;
        do {
            numAttempts++;
            try {
                preInvokeLog(point);
                Object retValue = point.proceed();
                postInvokeLog(point);
                return retValue;
            } catch (ServiceException e) {
                lastException = handleServiceException(point, numAttempts, e);
            }
        } while (numAttempts <= maxRetries);
        throw lastException;
    }

    ....
}
Run Code Online (Sandbox Code Playgroud)

这是我的服务类:

public class UserApiImpl implements UserApi {

    ...

    @Override
    public List<DomainUser> retrieveSuspendedUsers() throws Exception{
        LOG.debug("Retrieving suspended users.");

        ...

        List<DomainUser> users = new ArrayList<DomainUser>(64);
        do {
            //Invoke API. AOP invoke it two times! 
            currentPage = getUsers(retrieveUrl);
                    ...
                    URL nextLink = currentPage.getNextLink();
                    if (nextLink == null){
                        break;
                    }
            ...
        } while (nextLink != null);

        return users;
    }

    @Override
    @RequestRetriable
    public UserFeed getUsers(URL feedUrl) throws Exception {
        return userService.getFeed(feedUrl, UserFeed.class);
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

如您所见,我只注释了getUsers方法.方法retrieveSuspendedUsers未注释.

Spring配置如下所示:

<aop:aspectj-autoproxy/>
Run Code Online (Sandbox Code Playgroud)

现在,当我直接调用getUsers方法时,一切正常 - AOP只调用一次.但是当我调用retrieveSuspendedUsers方法时 - AOP为每个页面调用两次(我逐页检索用户,页面大小等于100).我可以在下面的日志中看到:

2013-03-11 13:06:40,179 DEBUG [pool-2-thread-1] Invoke API request getUsers with arguments [https://domain.com/user/2.0/]
2013-03-11 13:06:40,180 DEBUG [pool-2-thread-1] Invoke API request getUsers with arguments [https://domain.com/user/2.0/]
2013-03-11 13:06:41,745 DEBUG [pool-2-thread-1] Invoke API request getUsers with arguments [https://domain.com/user/2.0/] finished successfully
2013-03-11 13:06:41,745 DEBUG [pool-2-thread-1] Invoke API request getUsers with arguments [https://domain.com/user/2.0/] finished successfully
Run Code Online (Sandbox Code Playgroud)

API调用非常耗时,我想避免额外的,不必要的调用.如何解决这个问题?

Rei*_*eus 5

AFAIK切入点拦截被称为切入点建议的事件callexecution事件.您可以过滤以仅匹配execution切入点中的方法:

@Around("execution(* *(..)) && @annotation(com.test.RequestRetriable)")
Run Code Online (Sandbox Code Playgroud)