vach
vach

Reputation: 11377

SpringAOP complex pointcut

uppose ther is a class A :

public class A {
    public B b;

    public void justDoIt1(){
        b.getB();
    }

    @SomeAnnotation
    public void justDoIt2(){
        b.getB();
    }
}

and class B:

public class B{
    public void getB(){
        System.out.println("get");
    }
}

How do we create pointcut to execution of B.getB() that is called from within a method annotated with @SomeAnnotation?

Here is what I've tried

@Aspect
public class LocalizationAspect {
    @Before(value = "@within(Localize) && execution(* B.getB())")
    public void aspectStuff() {
        System.out.println("aspect");
    }
}

just to make my point clear : expected output will be when calling justDoIt2();

aspect get

but when calling justDoIt1();

get

Note: i'm using SpringAOP (maybe it has some restrictions on this) Any help on this?

Upvotes: 0

Views: 184

Answers (1)

Andy Clement
Andy Clement

Reputation: 2560

If I were using plain AspectJ I would do this:

execution(* B.getB()) && cflow(@withincode(SomeAnnotation))

"execution of getB() in the control flow of a method annotated with SomeAnnotation. But this does mean it will get caught if deeper in the flow, which may not be what you want. e.g. if the method annotated with SomeAnnotation calls something which calls something else which then calls getB() - that will get caught by this advice.

I don't know how it'll behave under Spring AOP though.

EDIT: On further thinking, the pointcut above is perhaps not optimal as @withincode() might create more byte code than absolutely necessary. A more optimal version is probably:

execution(* B.getB()) && cflow(execution(@SomeAnnotation * *(..)))

@withincode(SomeAnnotation) will advise all join points within a method marked @SomeAnnotation, but you are probably only interested in the execution join point.

Upvotes: 1

Related Questions