Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get annotated method parameter and his annotation

In my application I have methods with parameters annotated by some annotation. Now I want to write Aspect that do some preprocessing on annotated parameters using information from annotation attributes. For example, method:

public void doStuff(Object arg1, @SomeAnnotation CustomObject arg1, Object arg2){...}

aspect:

@Before(...)
public void doPreprocessing(SomeAnnotation annotation, CustomObject customObject){...}

What should be written in @Before?

Edit:

Thanks to everyone. There is my sollution:

@Before("execution(public * *(.., @SomeAnnotation (*), ..))")
public void checkRequiredRequestBody(JoinPoint joinPoint) {
    MethodSignature methodSig = (MethodSignature) joinPoint.getSignature();
    Annotation[][] annotations = methodSig.getMethod().getParameterAnnotations();
    Object[] args = joinPoint.getArgs();

    for (int i = 0; i < args.length; i++) {
        for (Annotation annotation : annotations[i]) {
            if (SomeAnnotation.class.isInstance(annotation)) {
                //... preprocessing
            }
        }
    }
}
like image 493
2dy Avatar asked May 30 '14 08:05

2dy


1 Answers

You would do it like this:

@Before("execution(* com.foo.bar.*.doStuff(..)) && args(arg1, arg2)")
    public void logSomething(JoinPoint jp, CustomObject arg1, Object arg2) throws Throwable {

        MethodSignature methodSignature = (MethodSignature) jp.getSignature();
        Class<?> clazz = methodSignature.getDeclaringType();
        Method method = clazz.getDeclaredMethod(methodSignature.getName(), methodSignature.getParameterTypes());
        SomeAnnotation argumentAnnotation;
        for (Annotation ann : method.getParameterAnnotations()[0]) {
            if(SomeAnnotation.class.isInstance(ann)) {
                argumentAnnotation = (SomeAnnotation) ann;
                System.out.println(argumentAnnotation.value());
            }
        }
    }

This is the parameter type custom annotation:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface SomeAnnotation {
    String value();
}

And the method to be intercepted:

public void doStuff(@SomeAnnotation("xyz") CustomObject arg1, Object arg2) {
        System.out.println("do Stuff!");
    }

You cannot do it like

@Before(...)
public void doPreprocessing(SomeAnnotation annotation, CustomObject customObject){...}

because the annotation is not a parameter and in there you can only reference parameters. You could have done your way with using @args(annot) but this matches only the annotations that are placed on the argument type itself, not in front of the actual argument. @args(annot) is for cases like this:

@SomeAnnotation
public class CustomObject {

}
like image 121
Andrei Stefan Avatar answered Oct 08 '22 00:10

Andrei Stefan