Рекурсия с использованием AspectJ - PullRequest
6 голосов
/ 27 августа 2011

Я довольно новичок в AspectJ и у меня есть проблема, которая, несмотря на некоторые исследования, я не могу исправить.У меня есть следующий аспект, касающийся банка, который проверяет, удерживается ли баланс банка после каждого открытого вызова метода.

pointcut BankCheck(Bank bank): call(public * Bank.*(..)) && target(bank);

Object around(Bank bank): BankCheck(bank) {
    int balance = bank.getTotalBalance();
    Object result = proceed(bank);
    if (balance != bank.getTotalBalance()) {
        LOGGER.warn("The total balance of the bank is not equal.");
    } else {
        LOGGER.info("Ok");
    }
    return result;
}

Проблема заключается в том, что в аспекте я использую метод bank.getTotalBalance ()который сам по себе является методом публичного банка.Поэтому этот аспект рекомендуется каждый раз, и эта проблема рекурсии продолжается до тех пор, пока не будет создано исключение.Есть ли способ исправить это, например, отключив механизм извещения внутри аспекта?

Ответы [ 2 ]

4 голосов
/ 27 августа 2011

Попробуйте это:

public aspect BankTotalBalanceAspect {
    pointcut BankCheck(Bank bank): call(public * Bank.*(..)) && target(bank);

    Object around(Bank bank): BankCheck(bank) && !within(BankTotalBalanceAspect) {
        int balance = bank.getTotalBalance();
        Object result = proceed(bank);
        if (balance != bank.getTotalBalance()) {
            LOGGER.warn("The total balance of the bank is not equal.");
        } else {
            LOGGER.info("Ok");
        }
        return result;
    }    
}
0 голосов
/ 27 августа 2011

Я не слишком знаком с синтаксисом pointcut AspectJ, но есть ли у вас способ исключить вызов getTotalBalance из вашего определения pointcut? Это предотвратит рекурсию.

Кроме того, ваше определение точки отсечения в любом случае кажется слишком широким: я предполагаю, что проверка баланса, которую вы реализуете в своем аспекте, должна быть выполнена только для написания методов. Поэтому вызов только для чтения, такой как getTotalBalance, не должен совпадать. У вас есть способ различения методов readonly и методов записи в целевом классе, e. г. по существующим аннотациям транзакций или что-то в этом роде?

Если нет, вы можете сами ввести такие (пользовательские) аннотации и настроить свой pointcut, чтобы он соответствовал всем вызовам открытых методов, которые не помечены как доступные только для чтения. Но это будет означать изменение кода в целевом классе, что не всегда возможно. Но YMMV.

...