2

I am using Spring AOP with @AspectJ annotation style. I would like to get the value specified by an annotation, which can be used at either the method level or class level. For example:

My main annotation, which takes a value argument of type String:

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnnotation {

    String value();

}

Another annotation, which is used to ignore MyAnnotation when MyAnnotation is used at the class/type level and this IgnoreMyAnnotation is present at the method level:

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

}

Pointcuts and annotation advice:

@Aspect
@Component
public class MyAnnotationAdvice {

    @Pointcut("@annotation(myAnnotation)")
    public void methodHasMyAnnotation(MyAnnotation myAnnotation) {}

    @Pointcut("@within(myAnnotation)")
    public void classHasMyAnnotation(MyAnnotation myAnnotation) {}  

    @Pointcut("@annotation(com.mycompany.aop.IgnoreMyAnnotation)")
    public void methodIgnoresMyAnnotation() {}

    @Pointcut("methodHasMyAnnotation(myAnnotation) || (classHasMyAnnotation(myAnnotation) && !methodIgnoresMyAnnotation())")
    public void caresAboutMyAnnotation(MyAnnotation myAnnotation) {}

    @Before("caresAboutMyAnnotation(myAnnotation)")
    public void doSomethingWithAnnotationValue(JoinPoint jp, MyAnnotation myAnnotation) {

        /*
           when annotated at the class level, myAnnotation
           is defined and has expected value... but when
           annotated at the method level, myAnnotation is null!
        */
        String annotationValue = myAnnotation.value();

        // do something with annotationValue...

    }
}

And finally, a few use cases of MyAnnotation...

Used at class/type level:

@Service
@MyAnnotation("I can get this value no problem!")
public class MyServiceAImpl implements MyServiceA {

    public void doSomething() { /* ... */ }

    @IgnoreMyAnnotation
    public void doSomethingElse() { /* ... */ }

}

Used at method level:

@Service
public class MyServiceBImpl implements MyServiceB {

    @MyAnnotation("I can't get this value")
    public void doSomething() { /* ... */ }

}
cb4
  • 6,689
  • 7
  • 45
  • 57
hartz89
  • 669
  • 1
  • 6
  • 18
  • Yep, not sure how I didn't find it before but the solution there is exactly what I ended up doing. Closing... – hartz89 Apr 22 '16 at 18:57

0 Answers0