AspectJ - Retrieve list of annotated parameters

2020-07-23 08:51发布

问题:

From the following previous question (AspectJ - Presence of annotation in join point expression not recognized),

My goal: In an aspect, i'd like to be able to extract/retrieve all annotated parameters from matching functions, no matter how many there are. (and then apply some treatment on but it's not the scope of this question)

So for the moment, this is what i did (not working):

@Before("execution (* org.xx.xx.xx..*.*(@org.xx.xx.xx.xx.xx.Standardized (*),..))")
public void standardize(JoinPoint jp) throws Throwable {
    Object[] myArgs = jp.getArgs();
    getLogger().info("Here: arg length=" + myArgs.length);
    // Roll on join point arguments
    for (Object myParam : myArgs) {

        getLogger().info(
                    "In argument with " + myParam.getClass().getAnnotations().length
                                + " declaread annotations");
        getLogger().info("Class name is " + myParam.getClass().getName());
        // Get only the one matching the expected @Standardized annotation
        if (myParam.getClass().getAnnotation(Standardized.class) != null) {
            getLogger().info("Found parameter annotated with @Standardized");
            standardizeData(myParam.getClass().getAnnotation(Standardized.class), myParam);
        }
    }
}

This is the code matched by the advice:

public boolean insertLog(@Standardized(type = StandardizedData.CLIPON) CliponStat theStat) {
    // ...
}

And the traces generated by a junit test:

INFO: ICI: arg lenght=1
INFO: In argument with 0 declaread annotations

Looks like it doesn't detect the annotation

So my question is: how to detect parameters which have specific annotation(s) ?

Does somebody have an idea how to do it?

Thanks in advance for your help.

Regards.

Edit: i found this thread Pointcut matching methods with annotated parameters, discussing of the same thing, and applied the given solution but it doesn't work..

回答1:

I hope I understand you right.

myParam.getClass().getAnnotations() gives you the annotations on a class. Something like:

@Standardized(type = StandardizedData.CLIPON)
public class Main{...}

Maybe this pointcut/advice helps you:

@Before("execution (* org.xx.xx.xx..*.*(@org.xx.xx.xx.xx.xx.Standardized (*),..))")
public void standardize(JoinPoint jp) throws Throwable {
    Object[] args = jp.getArgs();
    MethodSignature ms = (MethodSignature) jp.getSignature();
    Method m = ms.getMethod();

    Annotation[][] parameterAnnotations = m.getParameterAnnotations();

    for (int i = 0; i < parameterAnnotations.length; i++) {
        Annotation[] annotations = parameterAnnotations[i];
        System.out.println("I am checking parameter: " + args[i]);
        for (Annotation annotation : annotations) {
            System.out.println(annotation);

            if (annotation.annotationType() == Standardized.class) {
                System.out.println("we have a Standardized Parameter with type = "
                        + ((Standardized) annotation).type());
            }
        }
    }
}

This gives me the following output:

I am checking parameter:  main.CliponStat@331f2ee1 
@annotation.Standardized(type=CLIPON)
we have a Standardized Parameter with type = CLIPON