2013-03-11 25 views
4

有时我的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); 
    } 

    ... 
} 

正如你所看到的,我只注解方法。方法retrieveSuspendedUsers未注释。

Spring配置是这样的:

<aop:aspectj-autoproxy/> 

现在,当我直接调用方法一切正常OK - 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 

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

+0

您可以登录程序线程名字也 – 2013-03-11 12:32:12

+0

如何'nextLink'的分配处理? – matsev 2013-03-11 12:32:24

+0

你的建议看起来不错,我的疑问是有人调用'getUsers'两次,如果你可以登录调用者线程,我们可以验证这个 – 2013-03-11 12:34:10

回答

4

AFAIK切入点拦截被称为切入点建议的callexecution事件。你可以筛选到你的切入点只匹配方法execution

@Around("execution(* *(..)) && @annotation(com.test.RequestRetriable)") 
+0

你是对的!有用!你让我今天一整天都感觉很好!现在它只调用一次,即使在我的“retrieveSuspendedUsers”方法中。我认为它默认只适用于“执行”。 – 2013-03-11 12:55:24