Я новичок в 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 (), который сам по себе является общедоступным методом банка. Поэтому аспект рекомендуется каждый раз, и эта проблема рекурсии продолжается до тех пор, пока не будет устранено исключение. Есть ли способ исправить это, например, отключив механизм подсказок внутри аспекта?

6
Joris Mees 27 Авг 2011 в 14:38

2 ответа

Лучший ответ

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

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;
    }    
}
4
Constantiner 27 Авг 2011 в 15:30

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

Вдобавок, ваше определение pointcut в любом случае кажется слишком широким: я предполагаю, что проверка баланса, которую вы реализуете в своем аспекте, должна выполняться только для написания методов. Таким образом, вызовы только для чтения, такие как getTotalBalance, в любом случае не должны сопоставляться. Есть ли у вас способ различать методы только для чтения и записи в целевом классе, например? грамм. по существующим аннотациям транзакций или что-то в этом роде?

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

0
Axel Knauf 27 Авг 2011 в 12:49