我正在尝试使用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;
}
}
如何成功获取第二种方法的返回值?
答案 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);
}