What's the difference between pointcut demoExecs(): within(Demo) && execution(* *(..)); and Pointcut demoExecs() : execution(* Demo.*(..)); Is there any?
A common question when people learn about this. Here is some code:
public class Demo { public void foo() {} }
class Bar extends Demo { public void foo() {} public void bar() {} }
aspect X { before(): execution(* *(..)) && within(Demo) {} before(): execution(* Demo.*(..)) {} }
Compile it and you’d see that the first before() advice matches Demo.foo() only. The second before() advice matches Demo.foo() *and* Bar.foo().
within() is about lexical scoping, the join point (in this case the execution join point) *must* be within the Demo class if you specify within(Demo).
However, (from the developers notebook I referred you to in the other post), call/execution/get/set join points may potentially have multiple signatures. If any of these signatures match a pointcut, then it is considered a match. The execution join points for the foo method in Bar are:
void Bar.foo() void Demo.foo()
That second join point exists because it is overriding the foo() method in Demo.
So the Bar.foo() method actually matches your execution(* Demo.*(..)) pointcut.
Isn't joining execution(void go()) && !execution(* go()) leaving you with an empty intersection in the following example? pointcut goCut(): cflow(this(Demo) && execution(void go())); pointcut demoExecs(): within(Demo) && execution(* *(..)); Object around(): demoExecs() && !execution(* go()) && goCut()
Let’s write out that _expression_ all together:
Object around(): within(Demo) && execution(* *(..)) && !execution(* go()) && cflow(this(Demo) && execution(void go()))
So we are looking for executions of any method in the Demo class except the go method which are occurring in the control flow of the go method in Demo.
So we are looking for bar here:
class Demo { void go() { bar(); } void foo() { bar(); } void bar() { // if we are here because go() called us, run the advice. If we are here because foo() called us, don’t run the advice. } }
Is the difference between pointcut goCut(): cflow(this(Demo) && execution(void go())); and Pointcut gocut(): execution(void Demo.go()); that the first means go() got kicked off by Demo, whereas the second line might have been kicked off from the outside (go() is default protected)?
The first means we are interested in anything that happens downstream during the execution of a go() method on something ‘instance of’ Demo, which might be a load of join points, you really shouldn’t ever see advice against just a cflow - cflow is a dynamically scoping pointcut (where within is statically scoping). And as per what I wrote in the other post, you really want a kinded pointcut alongside it, and possible a contextual pointcut designator.
The second means we are interested in just execution of Demo.go().
class Demo { void go() { bar(); } void bar() { // Execution of this method is in the cflow() of "this(Demo) && execution(void go())” but it is not going to match "execution(void Demo.go())" } }
Andy
Hi all, I have a few more questions, this time regarding this example: https://eclipse.org/aspectj/doc/released/progguide/examples-basic.html#examples-joinPointsWhat's the difference between pointcut demoExecs(): within(Demo) && execution(* *(..)); and Pointcut demoExecs() : execution(* Demo.*(..)); Is there any? Isn't joining execution(void go()) && !execution(* go()) leaving you with an empty intersection in the following example? pointcut goCut(): cflow(this(Demo) && execution(void go())); pointcut demoExecs(): within(Demo) && execution(* *(..)); Object around(): demoExecs() && !execution(* go()) && goCut() Is the difference between pointcut goCut(): cflow(this(Demo) && execution(void go())); and Pointcut gocut(): execution(void Demo.go()); that the first means go() got kicked off by Demo, whereas the second line might have been kicked off from the outside (go() is default protected)? Kind regards, Christian _______________________________________________ aspectj-users mailing list aspectj-users@xxxxxxxxxxx To change your delivery options, retrieve your password, or unsubscribe from this list, visit https://dev.eclipse.org/mailman/listinfo/aspectj-users
|