30

I have two annotation @LookAtThisMethod and @LookAtThisParameter, if I have a pointcut around the methods with @LookAtThisMethod how could I extract the parameters of said method which are annotated with @LookAtThisParameter?

For example:

@Aspect
public class LookAdvisor {

    @Pointcut("@annotation(lookAtThisMethod)")
    public void lookAtThisMethodPointcut(LookAtThisMethod lookAtThisMethod){}

    @Around("lookAtThisMethodPointcut(lookAtThisMethod)")
    public void lookAtThisMethod(ProceedingJoinPoint joinPoint, LookAtThisMethod lookAtThisMethod) throws Throwable {
        for(Object argument : joinPoint.getArgs()) {
            //I can get the parameter values here
        }

        //I can get the method signature with:
        joinPoint.getSignature.toString();


        //How do I get which parameters  are annotated with @LookAtThisParameter?
    }

}
Bobby
  • 18,217
  • 15
  • 74
  • 89

2 Answers2

56

I modeled my solution around this other answer to a different but similar question.

MethodSignature signature = (MethodSignature) joinPoint.getSignature();
String methodName = signature.getMethod().getName();
Class<?>[] parameterTypes = signature.getMethod().getParameterTypes();
Annotation[][] annotations = joinPoint.getTarget().getClass().getMethod(methodName,parameterTypes).getParameterAnnotations();

The reason that I had to go through the target class was because the class that was annotated was an implementation of an interface and thusly signature.getMethod().getParameterAnnotations() returned null.

Community
  • 1
  • 1
Bobby
  • 18,217
  • 15
  • 74
  • 89
  • 2
    Thank you so much. I've wasted a lot of time before finding this answer. – Stephen Paul Jul 10 '14 at 13:42
  • 2
    For me `signature.getMethod().getParameterAnnotations()` returns the method of the interface and not the implementation. So if the annotation are only on the implementation, the will be null with this call. – oleh Feb 27 '15 at 13:39
  • 2
    `signature.getMethod().getAnnotation()` also works. Just remember annotation should have `@Retention(RetentionPolicy.RUNTIME)`. – Kaushik May 16 '15 at 17:02
  • 1
    "The reason that I had to go through the target class was because the class that was annotated was an implementation of an interface" this is important if the annotation is in the class impl rather than the interface...thanks @soldier.moth – Dexter Legaspi Oct 06 '16 at 13:53
  • there are 2 optional pitfalls in this line: ```Annotation[][] annotations = joinPoint.getTarget().getClass().getMethod(methodName, parameterTypes).getParameterAnnotations();``` 1. `joinPoint.getTarget().getClass()` might return enhanced name (`*$$CGLIB..`) which will cause `getMethod(..)` to fail 2. in case of non visible method - getMethod() will fail so if you already resolve the class - use `getDeclaredMethod` proposal: `Annotation[][] annotations = ClassUtils.getUserClass(jp.getTarget()).getDeclaredMethod(methodName, parameterTypes).getParameterAnnotations();` – ezer Dec 23 '20 at 10:27
5
final String methodName = joinPoint.getSignature().getName();
    final MethodSignature methodSignature = (MethodSignature) joinPoint
            .getSignature();
    Method method = methodSignature.getMethod();
    GuiAudit annotation = null;
    if (method.getDeclaringClass().isInterface()) {
        method = joinPoint.getTarget().getClass()
                .getDeclaredMethod(methodName, method.getParameterTypes());
        annotation = method.getAnnotation(GuiAudit.class);
    }

This code covers the case where the Method belongs to the interface

kirenpillay
  • 339
  • 1
  • 5
  • 7
  • This worked for me with one slight modification. I needed to use getMethod instead of getDeclaredMethod since my method was in a superclass. – Ken Joyner Mar 11 '16 at 20:23
  • The line `annotation = method.getAnnotation(GuiAudit.class);` should be placed after the if (and not inside it) – francisco neto May 17 '21 at 14:07