2013-03-11 86 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