shinjw
shinjw

Reputation: 3421

Spring AOP using method & parameter annotations

Is there a way to get Spring AOP to recognize the value of an argument that has been annotated? (There is no guarantee in the order of the arguments passed into the aspect, so I'm hoping to use an annotation to mark the parameter that needs to be used to process the aspect)

Any alternative approaches would also be extremely helpful.

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Wrappable {
}


@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface Key {
}

@Wrappable
public void doSomething(Object a, @Key Object b) {
    // something
}

@Aspect
@Component
public class MyAspect {
    @After("@annotation(trigger)" /* what can be done to get the value of the parameter that has been annotated with @Key */)
    public void trigger(JoinPoint joinPoint, Trigger trigger) { }

Upvotes: 5

Views: 10209

Answers (2)

Shanmuga Prabhu M
Shanmuga Prabhu M

Reputation: 111

We cannot get the parameter annotation value as an argument to AOP like we are doing it for the method annotation because the annotation is not an actual parameter and in there you can only reference actual arguments.

args(@Key b)

This annotation will give you the value of Object(b) not the value of @Key annotation.

We can do in this way to get the value of the parameter annotation:

MethodSignature methodSig = (MethodSignature) joinpoint.getSignature();
Annotation[][] annotations = methodSig.getMethod().getParameterAnnotations();
if (annotations != null) {
    for (Annotation[] annotArr : annotations) {
        for (Annotation annot : annotArr) {
            if (annot instanceof KeyAnnotation) {
                System.out.println(((KeyAnnotation) annot).value());
            }
        }
    }
}

Upvotes: 3

Indra Basak
Indra Basak

Reputation: 7394

Here is an example of an aspect class which should process a method tagged with @Wrappable annotation. Once the wrapper method is called, you can iterate over method parameters to find out if any parameter is tagged with the @Key annotation. The keyParams list contains any parameter tagged with a @Key annotation.

@Aspect
@Component
public class WrappableAspect {

    @After("@annotation(annotation) || @within(annotation)")
    public void wrapper(
            final JoinPoint pointcut,
            final Wrappable annotation) {
        Wrappable anno = annotation;
        List<Parameter> keyParams = new ArrayList<>();

        if (annotation == null) {
            if (pointcut.getSignature() instanceof MethodSignature) {
                MethodSignature signature =
                        (MethodSignature) pointcut.getSignature();
                Method method = signature.getMethod();
                anno = method.getAnnotation(Wrappable.class);

                Parameter[] params = method.getParameters();
                for (Parameter param : params) {
                    try {
                        Annotation keyAnno = param.getAnnotation(Key.class);
                        keyParams.add(param);
                    } catch (Exception e) {
                        //do nothing
                    }
                }
            }
        }
    }
}

Upvotes: 5

Related Questions