4

APIが例外をスローすることがあり、そのサーバーは私のリクエストを処理できません。API呼び出しを再度呼び出すAOPアスペクトを作成することにしました。たとえば、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は1回だけ呼び出します。しかし、retrieveSuspendedUsersメソッドを呼び出すと、AOPはページごとに2回呼び出します(ページサイズが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呼び出しは非常に時間がかかるため、追加の不要な呼び出しは避けたいと思います。この動作を修正する方法は?

4

1 に答える 1

5

AFAIKポイントカットインターセプトは、ポイントカットアドバイスのイベントcallとイベントの両方で呼び出されます。ポイントカットのexecutionメソッドのみに一致するようにフィルタリングできます。execution

@Around("execution(* *(..)) && @annotation(com.test.RequestRetriable)")
于 2013-03-11T12:40:42.950 に答える