How to get the annotated annotation according to the annotation?

Posted by zuessh on Sat, 21 Mar 2020 16:53:28 +0100

Give an example:

For example, you should know that the @ Repository, @ Service, @ Controller annotations in the Spring framework are all marked by the @ Component annotation in the source code

Question:

  1. Can you find the classes marked by @ Repository, @ Service, @ Controller by scanning @ Component annotation in native reflection or Spring framework?
  2. If not, why should the @ Component annotation be annotated in the @ Repository, @ Service, @ Controller annotation?

Code

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

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

@RedTag
class TagDemo{
    public static void main(String[] args) {
        Annotation[] annotations = TagDemo.class.getAnnotations();
        System.out.println("Annotation[]: " +Arrays.toString(annotations));
        // Annotation[]: [@pub.guoxin.demo.gateway.dr.prvd.RedTag()]

        Tags annotation = TagDemo.class.getAnnotation(Tags.class);
        System.out.println("Tags: " + annotation);
        // Tags: null
    }
}

 

All annotations are essentially interfaces inherited from Annotation.

    @Target(ElementType.ANNOTATION_TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Foo {
        String value();
    }

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Foo("test")
    public @interface Bar { }

    @Bar
    static class C { }

    public static void main(String ...args) throws NoSuchFieldException, IllegalAccessException {
        Bar bar = C.class.getAnnotation(Bar.class);
        InvocationHandler handler = Proxy.getInvocationHandler(bar);
        Field field = handler.getClass().getDeclaredField("type");
        field.setAccessible(true);
        Class<?> clazz = (Class<?>) field.get(handler);
        if (clazz.isAnnotationPresent(Foo.class)) {
            Foo foo = clazz.getAnnotation(Foo.class);
            System.out.println(foo.value()); // "test"
        }
    }

Suppose Foo is Component and Bar is Service, which can be obtained by analogy.

It should be noted that the annotation instance obtained through reflection is actually a proxy class. After all, the annotation compiled is only an interface, so the value operation of annotation attribute needs to be implemented by proxy class, so it can't directly get annotation on the annotation instance obtained.

Topics: Programming Spring Attribute