(Title isn't the best, but I couldn't find a good way to phrase the following problem)
Given
@Aspect
@Component
class MyAspect {
@Autowired private MyService service;
@Around("@target(org.springframework.ws.server.endpoint.annotation.Endpoint)")
public Object aroundEndpoint(ProceedingJoinPoint joinPoint) {
return service.around(joinPoint::proceed);
}
@Around("@target(org.springframework.stereotype.Service)") // And some other expressions to exclude `MyService`
public Object aroundService(ProceedingJoinPoint joinPoint) throws Throwable {
// ...
}
}
@Service
class MyService {
// My own Callable<T> with Throwable instead of Exception
public Object around(Callable<?> callable) throws Throwable {
// Do stuff
Object returnValue = callable.call();
// Do stuff
return returnValue;
}
}
When an endpoint method is invoked, it is intercepted by aroundEndpoint. If I were to invoke joinPoint.proceed() right away, everything would work as expected. However, if I pass it as a method reference (or a lambda) into MyService.around, and then invoke it, it is matched against my service pointcut and my around service advice is applied to it.
I did some debugging, and here's what I see: in AspectJExpressionPointcut.matches, thisObject and targetObject refer to my endpoint in the former case, but refer to my service in the latter case. This is probably because it uses ExposeInvocationInterceptor.currentInvocation(), and doing another method call messes with it.
Is this a bug? Some limitation of the proxy-based approach? Or do I have to simply inline MyService.aroundService?