2017-02-22 7 views
0

У меня есть приложение Spring Boot с несколькими классами, которые имеют общий класс HttpUtil, который обрабатывает запросы Http. В прошлом, я использовал AspectJ в следующем:Использование AspectJ для мониторинга времени выполнения вызова REST в приложении Spring Boot

@Around("execution(* com.gateway.TestGateway.getStatus(..))") 
public Object GatewayStatus(ProceedingJoinPoint pjp) throws Throwable { 
    StopWatch watch = new StopWatch(); 
    watch.start(); 
    Object output = pjp.proceed(); 
    watch.stop(); 
    log.error("Call took - [" + (watch.getTime()) + "]ms"); 
    return output; 
} 

Это работало отлично, я бы соответствовать getStatus() метод с @Around аннотацию, но структура шлюза теперь имеет код, окружающий вызов HTTPUTIL, и я только хотите профайл остального вызова. Новый метод шлюза выглядит следующим образом:

final HttpUtil httpUtil; //Constructor injected by Spring. 

public ResponseEntity<String> getResponse(final String serviceUrl, final HttpEntity<String> httpEntity) throws Exception { 

    ResponseEntity<String> response = null; 
    //Code here to verify the Entity 
    try{ 
     response = httpUtil.postEntity(serviceUrl, httpEntity, String.class, 
      httpUtil.getRestTemplate()); 
     //Logic here to work on the response. 
    } 
    catch(Exception e){ 
     log.error("Error occurred"); 
    } 
    return response; 
} 

Я понимаю, что я мог повторно фактор этого, или использовать профилировщик на самом методе класса HTTPUTIL, но как я могу использовать AspectJ, чтобы соответствовать фрагменту кода в рамках существующего метода ? Как и в, запустите, когда начинается звонок postEntity(), и после завершения вызова postEntity() заканчивается , но перед возвратом метода.

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

ответ

1

Когда Вы выбираете точку в вашей программе, в которой вы хотите применить советы и выполнить некоторые дополнительный код, например, выбор времени вызова postEntity() метода, вы должны создать точек соединения и Pointcut (ы) для выбранного должность. Pointcut определяет точки соединения, в которых будет применяться ваш совет (где начнется ваш код времени).

Итак, я думаю, что ваш вопрос конкретно о том, как определить pointcut при вызове postEntity() в классе ClassThatHasGetResponse.

Различные способы описания pointcuts задокументированы here и некоторые интересные примеры pointcut here.

Для вашего вопроса, вы можете иметь Pointcut так:

cflow(execution(Object ClassThatHasGetResponse.com.package.getResponse(..))) && call(* HttpUtil.postEntity(..)) 

выше срез точек определяет место, где управление потоком исполнения находится внутри метода getResponse() класса ClassThatHasGetResponse и вызов метода производится до postEntity() с любым типом возврата и любыми параметрами.

Вы должны добавить к Pointcut @Around совет, который фиксирует данные синхронизации, может быть, как это:

@Around("cflow(execution(Object ClassThatHasGetResponse.com.package.getResponse(..))) && call(* HttpUtil.postEntity(..))") 
public Object GatewayStatus(ProceedingJoinPoint pjp) throws Throwable { 
    StopWatch watch = new StopWatch(); 
    watch.start(); 
    Object output = pjp.proceed(); 
    watch.stop(); 
    log.error("Call took - [" + (watch.getTime()) + "]ms"); 
    return output; 
} 

Поскольку вы используете Spring, он также может быть стоит отметить, что в поддержку Спринга для AOP (это не то же самое, что AspectJ, но легко смутить использование одного и другого ИМО, особенно когда сначала узнаете о АОП через Spring при использовании AspectJ), pointcut (состоящий из точек соединения) всегда точка выполнения метода, что немного упрощает гибкость AspectJ. Source

+0

Благодарим за отзыв. Spring AOP не допускает вызова. У меня возникают проблемы с «внутри» части pointcut. Что я могу использовать вместо вызова? –

+0

Поздний отклик - но если вы используете Spring AOP, я думаю, вам придется придерживаться точки выполнения. Spring AOP поддерживает намного меньше pointcut, чем AspectJ.Если вы по-прежнему не хотите указывать pointcut в классе HttpUtil, вы можете определить метод «прокси», который вызывает только вызов HttpUtil postEntity(), и поместит точку point out вокруг метода прокси. – Luke

Смежные вопросы