简体   繁体   中英

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
            }
        }
    }
}

Here is an example that should work. (I didn't test it, but it should work)

@Before("execution(public * *(..))")
public void preprocessAnnotations(JoinPoint joinPoint) throws Throwable {

        MethodSignature methodSig = (MethodSignature) joinPoint.getSignature();
        Annotation[][] annotations = methodSig.getMethod().getParameterAnnotations();
        if(annotations != null){
            for(Annotation[] annotArr: annotations){
                for(Annotation annot: annotArr){
                    if(annot instanceof Resource){
                        String nameOfResource = ((Resource)annot).name();
                    }
                }
            }
        }



}

Here I added the test for javax.annotation.Resource justto show how to use the answer, but of course you should replace it with the annotations you need to process

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 {

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM