是否可以从 Spring AOP 中的相同建议中获取 return 值和方法参数?

Is it possible to get the return value and method arguments from the same advice in Spring AOP?

是否可以从 Spring AOP 中的相同建议中获取 return 值和方法参数?

我正在尝试根据 return 值和方法参数实现一些登录。

建议中需要使用所有这些信息来实现我的业务逻辑。

例如:

MyObject testMethod(String arg 1, String arg2){
    ..
    ..
    return myObject;
}

对于这种情况,我需要 myObject、arg1 和 arg2。

我尝试了以下带有两个不同注释的代码:@After 和 @AfterReturning,如下所示:

@AfterReturning(value="execution(* com.example.aop.service.TestServiceImpl.printTestData(..))", returning="test")
public void checkSomethingAfter(JoinPoint joinPoint, Test test) {
    System.out.println("------------AFTER RETURNING-----------");
    System.out.println("After execution - 111 " + joinPoint.getArgs());
    System.out.println("After execution - test: " + test);
    System.out.println("-------------------------------------");
}

// @After(value = "execution(* com.example.aop.service.TestServiceImpl.printTestData(..)) and args()")
    @After(value = "execution(* com.example.aop.service.TestServiceImpl.printTestData(..)) && args(id)")
    public void afterAdvice(JoinPoint joinPoint, int id) {
        System.out.println("After method:" + joinPoint.getSignature());
        System.out.println("Creating Test with id - " + id);
    }

问题是,我得到@After 中的参数和@Afterreturning 中的return 值。我的要求是同时在一个方法中获取 return 值和参数。

我该怎么做?

确实可以。您需要 @Around 建议并阅读 ProceedingJoinPoint 中的参数。


 @Around("execution(* com.example.MyClass.testMethod(..))")
 public Object testAop(ProceedingJoinPoint pjp) throws Throwable {
    Object[] arguments = pjp.getArgs();
    Object result = pjp.proceed();
    // Do logic based on arguments + return value

    return result;
}

我确实觉得实现可能会变得有点粗略,所以如果它不是真正的横切关注点,那么也许最好围绕该方法编写您自己的委托。

也可以使用 @AfterReturning 注释。 这是一个例子。

假设我们在 com.test.TestService class:

中有这个方法
public Object test(String arg1, Integer arg2) { ... }

那么您的建议方法将如下所示:

@AfterReturning(
        pointcut="execution(* com.test.TestService.test(..)) && args(arg1,arg2)",
        argNames="arg1,arg2,returnedValue",
        returning="returnedValue")
public void logAfterTest(String arg1, Integer arg2, Object returnedValue) {
    // some logic
}