2017-02-22 58 views
0

我有一個Spring Boot應用程序,它有多個類共享一個可以發出Http請求的常見HttpUtil類。在過去,我已經使用了AspectJ在以下幾點:在Spring Boot應用程序中使用AspectJ監視REST調用的運行時間

@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()方法調用的一個點,你必須創建連接點切入點(S)您選擇位置。切入點定義您的建議將應用於哪些連接點(您的計時代碼將在哪裏啓動)。

所以,我認爲你的問題是關於如何在ClassThatHasGetResponse類中調用postEntity()來定義切入點。

描述切入點的不同方式記錄在here和一些不錯的切入點示例是here

對於你的問題,你可能有這樣的一個切入點:

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

,上面的切入點定義了那個地方執行的控制流是類ClassThatHasGetResponse的方法getResponse()和方法調用內部設爲到postEntity()與任何返回類型和任何參數。

你必須添加這個切入點@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,它也可能是值得一提的是,在Spring的支持對於AOP來說(這與AspectJ不一樣,但是很容易混淆關於使用一個與其他IMO,特別是當使用AspectJ首次瞭解Spring的AOP時),一個切入點(由連接點組成)總是這是方法執行的一個點,它簡化了AspectJ的靈活性。 Source

+0

感謝您的回覆。 Spring AOP顯然不允許調用。我在切入點的「內部」部分遇到問題。我可以用什麼來代替通話? –

+0

延遲響應 - 但如果您使用Spring AOP,我認爲您必須堅持執行切入點。 Spring AOP比AspectJ支持更少的切入點。如果你仍然不想把切入點放在HttpUtil類上,你可以定義一個只有HttpUtil postEntity()調用的「代理」方法,然後把執行切入點放在代理方法的周圍。 – Luke

相關問題