如何根据“注解”获得被标注的“注解”?

如何根据“注解”获得被标注的“注解”?

举例:

先举个例子大家应该都知道Spring框架中的@Repository、@Service、@Controller这几个注解在源码中都被@Component注解所标注

问题:

  1. 在原生反射或者Spring框架中可以通过扫描@Component注解就能找到@Repository、@Service、@Controller所标注的类吗?
  2. 如果不能,那@Component注解为什么要标注在@Repository、@Service、@Controller注解中求解?

代码

@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
    }
}
阅读 3.9k
1 个回答

所有注解本质上都是继承自 Annotation 的接口 (interface)。

    @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"
        }
    }

假设 FooComponentBarService,可以类比得到。


要注意的是,通过反射拿到的注解实例实际上是代理类,毕竟前面说了注解编译后只是个接口,所以注解属性的取值操作都需要靠代理类来实现,所以不能直接在拿到的注解实例上去 getAnnotation

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题