【问题标题】:Spring AOP/AspectJ logging the execution time of a method but how to pass arguments to it? (Spring boot API)Spring AOP/AspectJ 记录方法的执行时间,但如何将参数传递给它? (春季启动 API)
【发布时间】:2021-02-23 22:18:25
【问题描述】:

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

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

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

【问题讨论】:

    标签: java spring aop aspectj


    【解决方案1】:

    您可以尝试在注解中添加带有您想要的内容的字符串:

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

    【讨论】:

      【解决方案2】:

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

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

      例如我会假装我正在跟踪某种方法,它采用“学生”数据类型,其中包含学生的一堆数据(姓名、出生日期、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;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-05-15
        • 1970-01-01
        • 2013-03-22
        • 2013-03-17
        • 2019-01-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多