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



我在Spring Boot API中使用Spring AOP/AspectJ在Java中进行注释,如@TrackExecutionTime,我可以在任何方法上添加注释,并记录该方法运行的总时间。这是目前在我的春季启动工作。我的问题是,我的API每天被击中数千次,我想记录一些其他独特的信息与这个执行时间,所以我可以跟踪/跟踪每个请求通过我的日志。我可以使用的一些数据是与JSON的POST请求体一起发送的,但是我不知道如何将这些参数传递到这个注释的定义中-有人可以帮助吗?

我想从这个客户传递一些参数(客户的名字,姓氏等)对象,即客户端将作为JSON发送到我的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 {
}

您可以尝试在注释中添加一个包含您想要的内容的String:

@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创建定义注释的接口时,在上面列出的具体类中,它可以访问从procedingjoinpoint传递给方法的所有参数对象。因此,您可以在该对象上调用getArgs(),以便在该方法运行时获得传递给该方法的所有参数。它将返回一个Object[],所以你只需要有一些条件检查来将它转换为你选择的类型,并确保它不是空的,这样你就不会在运行时得到任何异常。如果客户端发送到您的API,并且您想要跟踪方法的执行时间,但可能您有数百/数千个请求,并且需要专门跟踪,这是有用的。哪些调用遵循哪些路径,哪些可能会减慢API的速度…所以从requestBody中发布额外的数据可能对你的日志有帮助…

。假设我正在跟踪某个方法,它接收了一个" student "数据类型,它保存了学生的一堆数据(姓名,学位,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;
}
}

方法:

public void someMethod(String input)  

可以这样写切入点表达式:

@Around("@annotation(com.mailshine.springboot.aop.aspectj.advise.TrackExecutionTime) && args(input)")
public Object executionTime(ProceedingJoinPoint point, String input) throws Throwable {}

input参数现在可以很容易地用于executionTime方法。

最新更新