Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid hitting pointcut twice when the cut is on a superclass, but a derived class overrides?

It's tough to make a concise title for this.

Anyway, imagine I have a parent class:

    public class Shape {
        public Dimensions getDimensions() {
            // Does some generic stuff.
        }
    }

I have a derived class from it that overrides the getDimensions method:

    public class Circle extends Shape {
        public Dimensions getDimensions() {
            // Does some stuff.
            super.getDimensions();
        }
    }

When I create an aspect with a pointcut on Shape.getDimensions, the pointcut is hit twice when Circle.getDimensions is called: once for Circle.getDimensions, then once when it calls super.getDimensions.

The pointcut looks something like this: @Pointcut("execution(* Shape.getDimensions(..))")

I've added a hack inside the advice to check the declaring type's name (using JoinPoint.getSignature().getDeclaringType().getName()), but I find it rather gross and it feels kind of like a hack. I figure there MUST be a better way to do this.

Is there?

Apologies if the formatting isn't very good. First time asking a question on here (I can usually find the answer already).

like image 998
Depressio Avatar asked Aug 31 '12 00:08

Depressio


1 Answers

Probably you meant that your pointcut uses Shape+.getDimensions() (with the plus sign), otherwise it would not have matched Circle at all.

Anyway, you can solve the problem like this (I hope native AspectJ syntax is okay for you, I find it so much clearer and more expressive):

public aspect ShapeAspect {
    pointcut getDimensions() : execution(* Shape+.getDimensions());
    pointcut getDimensionsNoSuper() : getDimensions() && !cflowbelow(getDimensions());

    after() : getDimensionsNoSuper() {
        System.out.println(thisJoinPointStaticPart);
    }
}
like image 80
kriegaex Avatar answered Sep 26 '22 16:09

kriegaex