Как избежать попадания точек в два раза, когда разрез на суперклассом, а производный класс переопределяет?


Трудно сделать краткое название для этого.

В любом случае, представьте, что у меня есть родительский класс:

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

У меня есть производный класс от него, который переопределяет метод getDimensions:

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

Когда я создаю аспект с точечным разрезом на Shape.getDimensions, точечный разрез ударяется дважды, когда Circle.getDimensions вызывается: один раз для Circle.getDimensions, а затем один раз, когда он вызывает super.getDimensions.

Точечный разрез выглядит примерно так: @Pointcut("execution(* Shape.getDimensions(..))")

Я добавил Хак в совет, чтобы проверить имя объявляющего типа (используя JoinPoint.getSignature().getDeclaringType().getName()), но я нахожу это довольно грубым, и это похоже на взлом. Я думаю, что должен быть лучший способ сделать это.

Есть ли?

Извиняюсь, если форматирование не очень хорошее. Первый раз задаю вопрос здесь (обычно я уже могу найти ответ).

1 6

1 ответ:

Вероятно, вы имели в виду, что ваш pointcut использует Shape+.getDimensions() (со знаком плюс), иначе он вообще не соответствовал бы Circle.

В любом случае, вы можете решить эту проблему следующим образом (я надеюсь, что родной синтаксис AspectJ подходит для вас, я нахожу его намного более ясным и выразительным):

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

    after() : getDimensionsNoSuper() {
        System.out.println(thisJoinPointStaticPart);
    }
}