Spring AOP считает количество вызовов определенного метода из другого - PullRequest
2 голосов
/ 30 января 2011

У меня есть интерфейс с методом rangeQuery(), который я пытаюсь профилировать по всем подтипам, используя Spring AOP.В частности, для любого вызова rangeQuery() я хотел бы знать, сколько раз он вызывает другой метод distance() для поля из его тела.

Я знаю, что мог бы написать метод, который подсчитывает всезвонки на расстояние следующим образом:

@Before("execution(* *.distance(..))") 
public void count(JoinPoint joinPoint) {
    count++
}

Однако, это не уловило бы, какой rangeQuery() вызов вызвал его.

Есть идеи?

Ответы [ 2 ]

0 голосов
/ 30 января 2011

В крайнем случае, в приведенном выше совете @Before вы можете использовать Thread.currentThread.getStackTrace() и посмотреть, является ли вызывающий абонент rangeQuery.

Тем не менее, вы должны найти какой-то фиксированный «шаблон» для поиска в трассировке стека, а не просто проверить N-ю позицию, чтобы увидеть, является ли этот метод искомым. Например, последовательность методов, которую вы знаете, должна находиться в стеке в то время в некотором заданном порядке, но позволяя возникать любым другим элементам промежуточного стека. В противном случае любые изменения в вашем коде приведут к тому, что совет перестанет работать.

0 голосов
/ 30 января 2011

Вместо использования @Before вам, вероятно, придется использовать @Around, что позволяет вам использовать ProceedingJoinPoint для получения исходного местоположения.

 @Around(" ..... ")
  public void test(ProceedingJoinPoint pjp) throws Throwable {

    SourceLocation sl = pjp.getSourceLocation();
    System.out.println(sl.getFileName());
    System.out.println(sl.getLine());
    System.out.println(sl.getWithinType());

    // allow through
    pjp.proceed();
  }

В вашем случае может показаться, что вам может потребоваться call вместо execution, но кажется, что call не поддерживается в Spring AOP: -

Другие типы pointcut

Полный язык AspectJ pointcut поддерживает дополнительный pointcut обозначения, которые не поддерживаются в Весна. Это: вызов, инициализация, преинициализация, статическая инициализация, получить, установить, обработчик, совет выполнения, внутри кода, cflow, cflowbelow, if, @this, и @withincode. Использование этих pointcut обозначения в выражениях pointcut интерпретируется Spring AOP приведет в исключении IllegalArgumentException выброшены.

...