java - 使用 AspectJ 监控 Spring Boot 应用程序中 REST 调用的运行时间

标签 java spring aspectj

我有一个 Spring Boot 应用程序,其中包含多个类,这些类共享一个发出 Http 请求的通用 HttpUtil 类。过去,我曾在以下场合使用过 AspectJ:

@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() 调用完成之后在方法返回之前运行。

我对切入点和其他 AspectJ 属性不太熟悉。我想做的只是记录执行时间,但我想了解有关 AspectJ 的更多信息。

最佳答案

当您在程序中选择要应用建议并执行一些额外代码(例如对 postEntity() 方法调用进行计时)的点时,您必须创建连接点切入点为您选择的位置。切入点定义了您的建议将应用的连接点(计时代码将开始的位置)。

所以,我认为您的问题具体是关于如何在 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 中很容易对使用其中一个与另一个感到困惑,尤其是当第一次通过Spring学习AOP,同时使用AspectJ),切入点(由连接点组成)始终是方法执行点,这从AspectJ的灵 active 上简化了一点。 Source

关于java - 使用 AspectJ 监控 Spring Boot 应用程序中 REST 调用的运行时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42380875/

相关文章:

java - 仅当 bean 作为方法参数存在时,Spring 才会 Autowiring

java - Spring Transaction - 记录新事务的方法执行时间

maven - aspectj-maven-plugin 没有执行?

java - 替换方程中的未知变量

java - JavaDoc 预格式化文本 block 中允许使用 <sub> 和 <sup> 吗?

java - 在 Java 应用程序中使用 C 源代码的最简单方法是什么?

java - Spring RabbitTemplate - 如何在发送时自动创建队列

java - 在 J2SSH 中断开 NETCONF session 时线程被阻止

java - Spring boot 项目生成问题

java - 如何使用 Java 7 和 maven 启用 aspectj 编译时编织