[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[aspectj-users] How to get inner annotation instance from '@(@Foo *)' expression
|
This question might be a little esoteric, but still I am wondering how to solve the following problem without using reflection:
Lately I discovered that I can express "classes annotated by some annotation which in turn is annotated by another annotation Y" like this:
within(@(@Y *) *)
Here is a little example:
-------------------------------------------------
package de.scrum_master.app;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface OuterAnnotation {}
-------------------------------------------------
package de.scrum_master.app;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@OuterAnnotation
public @interface InnerAnnotation {}
-------------------------------------------------
package de.scrum_master.app;
import java.lang.annotation.Annotation;
@InnerAnnotation
public class Application {
public static void main(String[] args) {
for (Annotation annotation : Application.class.getAnnotations())
System.out.println(annotation);
}
}
-------------------------------------------------
Console log:
@de.scrum_master.app.InnerAnnotation()
-------------------------------------------------
Of course, the annotations on interfaces are never inherited or accumulated in any way by the JVM, so it is no surprise that Application has @InnerAnnotation, but not @OuterAnnotation. So far, so good.
But still I am able to say to AspectJ: Give me classes annotated by some annotation X which itself is annotated by @OuterAnnotation:
-------------------------------------------------
package de.scrum_master.aspect;
import de.scrum_master.app.OuterAnnotation;
public aspect MetaAnnotationAspect {
after() : within(@(@OuterAnnotation *) *) && execution(* *(..)) {
System.out.println("@OuterAnnotation -> " + thisJoinPoint);
}
}
-------------------------------------------------
Console log:
@de.scrum_master.app.InnerAnnotation()
@OuterAnnotation -> execution(void de.scrum_master.app.Application.main(String[]))
Besides, this is not just a theoretical example. In Spring you could e.g. want to capture all methods which are somehow connected with @RequestMapping. But obviously current Spring versions use this annotation indirectly by decorating annotations such as by @GetMapping, @PostMapping by @RequestMapping. Here the syntax mentioned above comes in handy because now you can have a method like
@GetMapping public void blah()
and capture it like this:
after() : execution(@(@RequestMapping *) * *(..)) {
System.out.println(thisJoinPoint);
}
This is really useful and it even works recursively. This gets all methods annotated by an annotation @X annotated by another annotation @Y annotated by @Target:
after() : within(@(@(@Target *) *) *) && execution(* *(..)) {
System.out.println(thisJoinPoint);
}
Now here is the actual question: Is there any way other than by reflection that I can bin the inner(most) annotation or any other annotation in the chain to pointcut arguments via @annotation(), @args() or whatever syntactic means so as to be able to inspect its properties? E.g. I could inspect which target types the @Target annotation in the above example has in its ElementType[]. I tried several syntax variations which might have done what I hoped for, such as trying to use (nested) versions of @within() or within(), but other than syntax errors the closest I could get to solving the problem was producing AspectJ compiler error dumps, giving me a slight hope that it might somehow work and just a compiler bug would be in the way.
So much for my (maybe not so) esoteric problem. I do not need it for production today, it is just a nifty little exercise, but I might use it tomorrow or next year if I know that it actually works.
Regards
--
Alexander Kriegisch
https://scrum-master.de