Полагаю, этот вопрос с его thisEnclosingJoinPointStaticPart
может вам помочь.
Но лучший способ решить вашу проблему - это построить правильную точку соединения, используя withincode
и call
pointcut, как в примере здесь (см. Contract Enforcement
раздел). Таким образом вы предотвращаете вызовы методов с определенной аннотацией или без нее.
Список точек доступен здесь здесь .
Что касается вашего примера кода, давайте введем аннотацию:
package com.riapriority.test;
public @interface CanEat {
}
Наш Banana
класс:
package com.riapriority.test;
public class Banana {
private static int bananaIdGen;
private final int bananaId = ++bananaIdGen;
private boolean eaten = false;
public void eat() {
if (eaten)
throw new IllegalStateException("Already eaten.");
else
eaten = true;
}
public int getBananaId() {
return bananaId;
}
}
Наш Monkey
класс с соответствующей аннотацией:
package com.riapriority.test;
public class Monkey {
@CanEat
public void feed(Banana b) {
b.eat();
}
}
Наш Airplane
класс, который, конечно, не может есть и поэтому не имеет @CanEat
аннотации:
package com.riapriority.test;
public class Airplane {
public void feed(Banana b) {
b.eat();
}
}
Наш простой основной класс для тестирования:
package com.riapriority.test;
public class WithincodeTest {
public static void main(String[] args) {
Banana monkeyBanana = new Banana();
Monkey monkey = new Monkey();
monkey.feed(monkeyBanana);
try {
monkey.feed(monkeyBanana);
} catch (IllegalStateException e) {
System.out.println(e.getMessage());
}
Banana airplaneBanana = new Banana();
Airplane airplane = new Airplane();
try {
airplane.feed(airplaneBanana);
} catch (IllegalStateException e) {
System.out.println(e.getMessage());
}
}
}
Так что нам нужно избегать употребления бананов самолетом. И соответствующий аспект для получения этого:
package com.riapriority.test;
import java.text.MessageFormat;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class EatingAspect {
@Pointcut("call(void Banana.eat()) && target(banana)")
public void eatCall(Banana banana) {
}
@Pointcut("@withincode(CanEat)")
public void canEat() {
}
@AfterReturning("eatCall(banana) && canEat()")
public void whereEaten(Banana banana,
JoinPoint.EnclosingStaticPart thisEnclosingStaticPart) {
System.out.println(MessageFormat.format("Banana {0} eaten by {1}", banana.getBananaId(),
thisEnclosingStaticPart.getSignature()));
}
@Before("eatCall(banana) && !canEat()")
public void forbidEating(Banana banana,
JoinPoint.EnclosingStaticPart thisEnclosingStaticPart) {
throw new IllegalStateException(MessageFormat.format("Can''t eat {0} by {1}", banana.getBananaId(),
thisEnclosingStaticPart.getSignature()));
}
}
Итак, теперь наш основной тестовый класс выдает правильный вывод:
Banana 1 eaten by void com.riapriority.test.Monkey.feed(Banana)
Already eaten.
Can't eat 2 by void com.riapriority.test.Airplane.feed(Banana)
Надеюсь, это решит вашу проблему.