微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Spring AOP/AspectJ 记录方法的执行时间,但如何将参数传递给它? (Spring 启动 API)

如何解决Spring AOP/AspectJ 记录方法的执行时间,但如何将参数传递给它? (Spring 启动 API)

我在我的 Spring Boot API 中使用 Spring AOP/AspectJ 在 Java 中做一个注释,比如 @TrackExecutionTime,我可以对任何方法进行注释,它会记录方法运行所花费的总时间。这目前在我的 Spring 启动中有效。我的问题是,我的 API 每天被命中数千次,我想用这个执行时间记录一些其他独特的信息,这样我就可以通过我的日志跟踪/跟踪每个请求。我可以使用的一些数据与 JSON 中的 POST 请求正文一起发送,但我看不到如何将这些参数传递到此注释的定义中 - 任何人都可以帮忙吗?

我想从这个 Customer 对象传递一些参数(客户名字、姓氏等),该对象是客户端将作为 JSON POST 到我的 API 到我的注释记录器的 requestBody:>

@RestController
public class CustomersController implements CustomersApi {

    @Autowired
    private CustomerService customerService;

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

我像这样定义了注解的具体类和接口。这是我想传递 Customer 对象的地方,以便我可以记录名字或姓氏:


@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 {
}

解决方法

您可以尝试在注释中添加包含您想要的内容的字符串:

@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();
}
,

这很容易做到;当我最初发布此内容时,我是个笨蛋,但对于希望做同样事情的人来说,这是一个答案:

当您使用 Spring AOP/AspectJ 创建定义注解的接口时,在我上面列出的具体类中,它可以访问从 ProceedingJoinPoint 对象传递给您的方法的所有参数。因此,您可以在此对象上调用 getArgs() 以获取在运行时传递给相关方法的所有参数。它将返回一个 Object[] ,因此您只需要进行一些条件检查即可将其转换为您选择的类型并确保其不为空,因此您在运行时不会遇到任何异常。如果客户端向您的 API 发送 POST 请求并且您想跟踪方法的执行时间,这将很有帮助,但也许您有数百/数千个请求并且需要专门跟踪准确地 哪些调用遵循哪些路径以及哪些可能会降低您的 API 速度...因此从 requestBody 发布额外数据可能对您的日志有所帮助...

例如我会假装我正在跟踪某种方法,该方法采用“学生”数据类型,其中包含有关学生的一堆数据(姓名、dob、gpa 等...)。这样,如果我有不同的方法根据客户端 POST 到 API 的 requestBody 使用不同的 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;
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。