SpringAOP/aspectj记录方法的执行时间,但如何向其传递参数(spring引导api)

wwodge7n  于 2021-07-23  发布在  Java
关注(0)|答案(2)|浏览(317)

我在我的springbootapi中使用springaop/aspectj以类似java的方式进行注解 @TrackExecutionTime ,我可以在任何方法上使用它,它会记录该方法运行所花费的总时间。这是目前在我的 Spring 启动工作。我的问题是,我的api一天中会被点击上千次,我想在这个执行时间内记录一些其他独特的信息,这样我就可以通过日志跟踪每个请求。我可以使用的一些数据是通过json的post请求体发送的,但是我看不出如何将这些参数传递到这个注解的定义中——有人能帮忙吗?
我想从这个客户对象中传递一些参数(customer firstname、lastname等),客户机将作为json发布到我的api到我的注解记录器:

@RestController
public class CustomersController implements CustomersApi {

    @Autowired
    private CustomerService customerService;

      return ResponseEntity.ok(offersService.fetchCustomer(Customer, clientId));
    }

我这样定义了具体的类和注解接口。这是我要传递customer对象的地方,以便我可以记录firstname或lastname:

@Aspect
@Component
@Slf4j
@ConditionalOnExpression("${aspect.enabled:true}")
public class ExecutionTimeAdvice {

    @Around("@annotation(com.mailshine.springboot.aop.aspectj.advise.TrackExecutionTime)")
    public Object executionTime(ProceedingJoinPoint point) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object object = point.proceed();
        long endtime = System.currentTimeMillis();

        log.info("Class Name: "+ point.getSignature().getDeclaringTypeName() +". Method Name: "+ point.getSignature().getName() + ". Time taken for Execution is : " + (endtime-startTime) +"ms");
        return object;
    }
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TrackExecutionTime {
}
yebdmbv4

yebdmbv41#

可以尝试将包含所需内容的字符串添加到注解中:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TrackExecutionTime {
    String getContent() default "";
}

在方法上使用它:

@TrackExecutionTime(getContent = "something")
private static void someMethod(...)

然后根据建议分析内容:

@Around("@annotation(myAnnotation)") 
public Object executionTime(ProceedingJoinPoint point, TrackExecutionTime myAnnotation)throws Throwable {
    ...
    String content = myAnnotation.getContent();
}
kadbb459

kadbb4592#

这是很容易做到的;当我最初发布这篇文章的时候,我是一个傻瓜,但是对于任何想做同样事情的人来说,这里有一个答案:
当您使用springaop/aspectj在上面列出的具体类中创建定义注解的接口时,它可以访问从proceedingjoinpoint对象传递给方法的所有参数。所以你可以打电话 getArgs() 在该对象上获取运行时传递给相关方法的所有参数。它将返回一个object[],因此您只需要进行一些条件检查,将它转换为您选择的类型,并确保它不是空的,这样在运行时就不会出现任何异常。如果客户机正在向您的api投递,并且您希望跟踪方法的执行时间,那么这会很有帮助,但是您可能有成百上千的请求,并且需要具体跟踪哪些调用遵循哪些路径,以及哪些可能会使您的api变慢。。。因此,从requestbody发布额外的数据可能有助于您的日志。。。
e、 g.我将假设我正在跟踪某个方法,该方法接受一个“student”数据类型,该类型包含一个学生的一系列数据(姓名、出生日期、平均绩点等)。这样,如果我有不同的方法,根据客户端发送到api的请求体,使用不同的sql查询来查询数据库,我就可以记录下来,准确地跟踪哪些请求减慢了api的速度,它们在代码库中的流动,以及它们调用的sql查询。即

@Aspect
@Component
@Slf4j
@ConditionalOnExpression("${aspect.enabled:true}")
public class ExecutionTimeAdvice {

    @Around("@annotation(com.mailshine.springboot.aop.aspectj.advise.TrackExecutionTime)")
    public Object executionTime(ProceedingJoinPoint point) throws Throwable {
        MyCustomStudentType student; // Class to hold Student data
        String studentName = "";
        Object[] argsArray = point.getArgs();

        if (argsArray.length > 0 && argsArray[0] instanceof MyCustomStudentType) {
             student = (MyCustomStudentType) argsArray[0];
             studentName = student.getName();
        }

        long startTime = System.currentTimeMillis();
        Object object = point.proceed();
        long endtime = System.currentTimeMillis();

        // add the student name to your logs or any info you want to add with your
        // execution time of your method, to make tracking your logs easier
        log.info("Class Name: "+ point.getSignature().getDeclaringTypeName() +". Method Name: "+ point.getSignature().getName() + ". Time taken for Execution is : " + (endtime-startTime) +"ms" + ", for student name: " + studentName);

        return object;
    }
}

相关问题