AfterReturning注释不适用于特定的方法结构

时间:2019-08-09 09:35:42

标签: java spring-boot aspectj spring-aop

我正在尝试使用AspectJ的@AfterReturning获得特定函数调用的返回值。

不确定为什么@AfterReturning在以下方法调用中不起作用。

尽管我试图在同一个类的2个方法上使用@AfterReturninging,但有1个方法在另一个不起作用时使用。 两种方法之间唯一的区别是参数数量,其中@AfterReturning适用于带有一个参数的方法。

  

工作

@AfterReturning(
  pointcut = "execution(org.springframework.http.ResponseEntity com.service.QueryGenerationService.method1(*))",
  returning = "retVal"
)
public void interceptMethod1(ResponseEntity retVal) {
  System.out.println(retVal+"---->");
}
  

不起作用

@AfterReturning(
  pointcut = "execution(com.entity.ReportGenerationExportResult com.service.QueryGenerationService.method2(com.entity.ReportGenerationServiceRequest, com.entity.querybuilder.QueryBuilderResponse))",
  returning = "retVal"
)
public void interceptMethod2(ReportGenerationExportResult retVal) {
  System.out.println(retVal);
}
  

通用规范也不起作用(用于2个方法参数)

@AfterReturning(
  pointcut = "execution(* com.service.QueryGenerationService.method2(*, *))",
  returning = "retVal"
)
public void test1(Object retVal){
  System.out.println(retVal);
}
  

存在2种方法的服务类

@Service
public class QueryGenerationService {

  public ResponseEntity method1(
    ReportGenerationServiceRequest request
  ) throws Exception
  {
    //some logic
    ReportGenerationExportResult exportResult = method2(request, queryBuilderResponse);
    return toResponseEntity(exportResult);
  }

  public ReportGenerationExportResult method2(
    ReportGenerationServiceRequest originalRequest,
    QueryBuilderResponse queryBuilderResponse
  ) throws Exception
  {
    //some logic
    return reportGenerationExportResult;
  }
}

如何成功获取第二种方法的返回值?

2 个答案:

答案 0 :(得分:2)

这是经典之作:您在错误的位置寻找答案。不是切入点是问题,您的应用程序类与Spring AOP的基于代理的性质结合在一起是:

如Spring手册在Understanding AOP Proxies章中明确解释的那样,Spring AOP不能用于自调用。

您的it('should call controller.ok when name is set', fakeAsync(() => { spyOn(nameService, 'doSomething').and.returnValue(Promise.resolve()); spyOn(controller, 'ok'); service.foo(); tick(); expect(controller.ok).toHaveBeenCalled(); })); 是直接从method2而不是从外部调用的,因此方法调用转到原始对象,而不是AOP代理。因此,任何方面都不会在那里触发。

如果您需要进行自调用的方面,则需要按照here所述从Spring AOP切换到功能齐全的ASpectJ。

答案 1 :(得分:0)

问题在您的正则表达式中。 link可以帮助您。

这两种方法的代码应类似...

 //interceptMethod2

@AfterReturning(pointcut = "execution(*   com.service.QueryGenerationService.method1(com.entity.ReportGenerationServiceRequest))", returning = "retVal")
public void interceptMethod2(ReportGenerationExportResult retVal) {
    System.out.println(retVal);
}


//generic method which execute for all the methods in class QueryGenerationService
@AfterReturning(
        pointcut = "execution(* com.service.QueryGenerationService.*(..))"
        , returning = "retVal")
public void test1(Object retVal){
    System.out.println(retVal);
}