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

发布于 2022-09-11 19:14:40 字数 1021 浏览 20 评论 0

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

举例:

先举个例子大家应该都知道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
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

枫以 2022-09-18 19:14:40

所有注解本质上都是继承自 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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文