【问题标题】:How to scan for a particular annotation of java classes loaded at runtime as a bytecode?如何扫描在运行时作为字节码加载的 java 类的特定注释?
【发布时间】:2015-04-13 06:29:40
【问题描述】:
  1. 如果 java 类在运行时作为字节码加载(例如,通过 ASM 库或其他机制),它是否位于 java 的类路径中?我没看到。
  2. 如何扫描以这种方式加载的类的所有注解,如果它不在 java 类路径上?

我使用谷歌反射和第三方库的自定义类加载器。

扫描类的工作原理如下:

            Reflections reflections = new Reflections(ClasspathHelper.forPackage("com.mypackage",
                    MyCustomClassLoader),
                    new SubTypesScanner(), new TypeAnnotationsScanner());
Set<Class<?>> myClasses = reflections.getTypesAnnotatedWith(MyAnnotation.class);

MyAnnotation - 标记为@Retention(RetentionPolicy.RUNTIME)。 以上(在一个类中)由JVM在运行时动态加载。

可以看出,在幕后,Reflections 尝试使用 2 个默认静态和上下文的类加载器来扫描所有 URL。

反射.scan()

更新:我找到了一个答案 Can you find all classes in a package using reflection?,说“如果有生成的类,或者远程交付,您将无法发现这些类。”但是,没有证据。 请任何人对此提供更多详细信息并确认?

【问题讨论】:

    标签: java reflection classloader reflections


    【解决方案1】:

    在运行时动态实例化类不会改变 JVM 正在使用的 类路径。发生的情况是某些 ClassLoader 类从某处获取字节码;并使其对您“可用”。但这绝不会改变加载类的“搜索顺序”(这基本上就是类路径的意义所在:它只告诉 JVM 在何处以及以何种顺序查找要加载的类)。

    含义:类的任何“加载”都会导致类 java.lang.Class 的某个对象。

    如果要查询任何已加载类的结构;你“只是”需要得到相应的 Class 对象。类提供了类似getAnnotation() 的方法。它还提供方法来检索表示特定类的方法和字段的其他对象;并且可以以类似的方式查询这些对象的注释。

    更新,关于问题中的更新:在某些情况下,您无权访问类来自的文件系统。当您知道类的名称时,您可以加载类,但您无法查看这些类所在的“位置”。这基本上会破坏您按预期使用反射的能力。

    没有必要“证明”这一点,这只是Java允许您在知道名称时加载类的结果,但“隐藏”了这些类来自“哪里”的确切内容.

    【讨论】:

    • 有没有办法不使用它的引用来获取这样一个类的类加载器,即:SomeClass.class.getClassLoader()。我需要扫描java包下的注释,但我不想尝试所有的类加载器,它很慢
    • 我猜这取决于您使用的库。 正常的事情应该是动态加载过程的结果......实际上是类Class的对象。因此,您可能想研究您正在使用的库的文档。此外:如果您已经可以输入“SomeClass.class” - 那么您不需要类加载器,因为 SomeClass.class 返回您正在寻找的 Class 对象。但当然,这只适用于在编译时已知的类。
    • 我得出结论,类加载器只能扫描其类路径下的项目。在运行时加载的注释不在类路径中。因此,问题仍然悬而未决。
    • 你没有得到它:你不需要 ClassLoader。您必须了解您的库如何加载类。正如我告诉过你的:Class 对象包含 all 结构信息。注释,就像 Java 类中的其他任何东西一样;因此,您可以通过这种方式获得所有必需的信息。
    • 你能解释一下为什么我需要知道一个带注释的类是如何加载的吗?是的,它以某种方式加载——这就足够了。但是通过谷歌反射扫描它不起作用。这个库引用类加载器来获取所有 URL 的集合。
    猜你喜欢
    • 1970-01-01
    • 2010-09-20
    • 2012-10-19
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 2021-08-10
    相关资源
    最近更新 更多