I'm pretty new to AspectJ and have a problem that inspite if some research I'm not able to fix. I have the following aspect concerning a Bank, the aspect checks whether the balance of the Bank holds after every public method invocation.
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;
}
The problem is that in the aspect I use the method bank.getTotalBalance() which is itself a public Bank method. Therefore the aspect is advised every time and this recursion problem keeps on going until an exception is trowed. Is there a way to fix this, for example by turning off the advise mechanism inside the aspect?
Try this:
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;
}
}
I am not all too familiar with AspectJ pointcut syntax, but do you have a way of excluding the getTotalBalance
call from your pointcut definition? This would prevent the recursion from happening.
In addition, your pointcut definition seems to match too broadly anyway: I assume that the balance check you implement in your aspect should be executed for writing methods only. So a readonly call like getTotalBalance
should not be matched anyway. Do you have a way of distinguishing between readonly and writing methods in the target class, e. g. by existing transaction annotations or something like that?
If not, you may want to introduce such (custom) annotations yourself and adjust your pointcut to match all public method calls which are not marked as readonly. But this would mean modifying the code in the target class, which is not always an option. But YMMV.
精彩评论