I'm using Spring AOP to intercept a method execution.
I have an interface that looks like the following:
public interface MyAwesomeService {
public Response doThings(int id, @AwesomeAnnotation SomeClass instance);
}
Here is the implementation of the interface:
public class MyAwesomeServiceImpl implements MyAwesomeService {
public Response doThings(int id, SomeClass instance) {
// do something.
}
}
Now i would like any method which has a parameter annotated with @AwesomeAnnotation should be captured by Spring AOP.
So I wrote the following aspect which works.
@Aspect
@Component
public class MyAwesomeAspect {
@Around("myPointcut()")
public Object doAwesomeStuff(final ProceedingJoinPoint proceedingJoinPoint) {
final MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
Annotation[][] annotationMatrix = methodSignature.getMethod().getParameterAnnotations();
// annotationMatrix is empty.
}
@Pointcut("execution(public * *(.., @package.AwesomeAnnotation (package.SomeClass), ..))")
public void myPointcut() {}
}
However when I try to find the parameter annotations I don't get any annotations back. As mentioned above, the annotationMatrix is empty.
So here are my questions:
- Why is the annotationMatrix empty? Probably because parameter annotations are not inherited from an interface.
- Why I'm able to capture the method execution. Since Spring AOP is able match the pointcut, Spring somehow is able to see the method's parameter annotations but when I try to see that using
methodSignature.getMethod().getParameterAnnotations()it doesn't work.
The answers to your questions:
Parameter annotations are not inherited from interfaces to implementing methods. In fact, annotations are almost never inherited, only from class (not interface!) to subclass if the annotation type itself is annotated by
@Inherited, see JDK API documentation. Update: Because I have answered this question several times before, I have just documented the problem and also a workaround in Emulate annotation inheritance for interfaces and methods with AspectJ.Because during compile or weave time AspectJ can match your pointcut against the interface method and thus sees the annotation.
You can fix the situation by adding the annotation to the parameter in your interface implementation, e.g. like this:
Then with an aspect like this...
... you get a console log similar to this: