Используйте aspectj для профилирования выбранных методов - PullRequest
4 голосов
/ 11 февраля 2009

Я хотел бы использовать aspectj для профилирования библиотеки. Мой план состоял в том, чтобы пометить методы, которые требуют профилирования, аннотацией:

@Profiled("logicalUnitOfWork")

И затем есть аспект, который запускается до и после методов, которые используют logicalUnitOfWork для выделения профилированного содержимого.

Итак, мой pointcut для начала выглядит следующим образом. Обратите внимание, что у меня нет аргумента для аннотации здесь; это одна из вещей, которые я не знаю, как это сделать:

pointcut profiled() : execution(@Profiled * *());

before() : profiled () {
    // : the profiled logical name is in this variable:
String logicalEventType;
Profiler.startEvent (logicalEventType);
}

after() returning : profiled() {
    // : the profiled logical name is in this variable:
String logicalEventType;
    Profiler.endEvent (logicalEventType);
}

Профилируемые методы будут определены следующим образом:

@Profiled("someAction")
public void doAction (args...) {}

Короче говоря, как я могу получить значение аннотации @Profiled в аспекте? Мне не нужно ограничивать, какое профилирование происходит в зависимости от значения, мне просто нужно, чтобы оно было видно совету. Кроме того, нужно ли для сохранения аннотации установить время выполнения, чтобы это работало, или вместо этого можно использовать сохранение на уровне класса?

Ответы [ 2 ]

2 голосов
/ 15 февраля 2009

Я не уверен, что это лучший способ сделать это, но вы можете попробовать что-то вроде:


   pointcut profiledOperation(Profiled p) : 
      execution(@Profiled * *()) && @annotation(p);

   before(Profiled p): profiledOperation(p)
   {
      System.out.println("Before " + p.value());
   }

   after(Profiled p): profiledOperation(p)
   {
      System.out.println("After " + p.value());
   }

Поскольку вам необходимо получить доступ к значению аннотации во время выполнения, вам придется установить @Retention на RUNTIME.

1 голос
/ 07 апреля 2009

Некоторое время назад я делал нечто подобное, чтобы аннотировать поля с "значениями по умолчанию". Я пытался адаптировать его к аннотированным методам, которые должны найти работу. Вы, конечно, должны добавить немного проверки ошибок и нулевого тестирования здесь, так как я оставил это для краткости.

Вы можете получить значение аннотации, используя статическую часть точки соединения.

private String getOperationName(final JoinPoint joinPoint) {
   MethodSignature methodSig = (MethodSignature) joinPoint
      .getStaticPart()
      .getSignature();
   Method method = methodSig.getMethod();
   Profiled annotation = method.getAnnotation(Profiled.class);
   return annotation.value();
}

Чтобы избежать слишком много размышлений, лучше использовать вместо around совет:

around(): profiled() {
   String opName = getOperationName(thisJoinPoint);
   Profiler.startEvent(opName);
   proceed();
   Profiler.endEvent(opName);
}
...