The simple answer is "yes, but..."
Keeping it simple, what AspectJ does is basically going pointcut-to-pointcut and searching how to weave it, and then, well, weaves it. In the case of two pointcuts to the same method, one of the pointcuts will weave and then the other one will weave and will basically override that first weaving. Unless the second pointcut proceeds!
Let me explain this with a short example. Suppose you have the following class:
public class TestClass {
public static void main(String... args) {
new TestClass().x();
}
public void x() {
System.out.println("Hello, world!");
}
}
Now let's define an aspect:
public aspect FirstAspect {
public pointcut hello1() : execution(void mypackage.TestClass.x());
void around() : hello1() {
System.out.println("first");
}
}
What will happen is that the aspect will weave the method x
, basically replace the call to x with a method that AspectJ created.
Now let's suppose we have another aspect:
public aspect SecondAspect {
public pointcut hello2() : execution(void mypackage.TestClass.x());
void around() : hello2() {
System.out.println("second");
}
}
With loss of generality and to be consistent, let us assume that FirstAspect
is weaved first. At that point, we have the same result as we had before. But now AspectJ continues and weaved SecondAspect
. It finds method x() and replaces its' execution (or call, depending on the pointcut type) with a new method, effectively overriding that previous weaving and leaving it obsolete (ironically enough, the first weaved code is remained but is useless).
However, if SecondAspect
's advice calls proceed()
at any point, then the part it will proceed to will actually be the first weaving. That's because because it weaved, that's what x was doing as far as AspectJ is concerned.
Try this out. You'll see only one of the pointcuts is actually left weaved: you'll only get one print: either first
or second
but not both, unless you proceed, as such:
System.out.println("second");
proceed();
It doesn't even matter when you proceed()
, as long as you do:
proceed();
System.out.println("second");
If you want to ensure which pointcut is weaved first, you can look at AspectJ precedence declaration
.