有时我的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;
}
....
}这是我的服务类:
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);
}
...
}如您所见,我只注释了getUsers方法。方法retrieveSuspendedUsers未被批注。
Spring配置如下所示:
<aop:aspectj-autoproxy/>现在,当我直接调用getUsers方法时,一切正常-- AOP只调用它一次。但是,当我调用retrieveSuspendedUsers方法时- AOP为每个页面调用它两次(我逐页检索页面大小等于100的用户)。我可以在log中看到以下几行:
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 successfullyAPI调用非常耗时,我希望避免额外的、不必要的调用。如何修复此行为?
发布于 2013-03-11 20:40:43
对于切入点通知的call和execution事件,都会调用AFAIK切入点截取。您可以过滤以仅匹配切入点中的方法execution:
@Around("execution(* *(..)) && @annotation(com.test.RequestRetriable)")https://stackoverflow.com/questions/15338277
复制相似问题