我使用google reflections和第三方库的自定义类加载器。
扫描类的工作方式如下:
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。
Reflection.Scan()
更新:我已经找到一个答案,你能找到所有的类在一个包使用反射?他说“如果有类是通过远程方式产生的,你将无法发现这些类。”但是没有证据。能请谁提供更多的细节和确认吗?
在运行时动态实例化类不会更改JVM正在使用的类路径。发生的情况是,某个类加载器类从某个地方获取字节码;并使它“可用”于你。但这丝毫不会改变加载类的“搜索顺序”(这也是类路径的基本内容:它只告诉JVM在何处以及以何种顺序查找要加载的类)。
意思:类的任何“加载”都会导致类java.lang.class的一些对象。
如果要查询任何加载类的结构;您“只”需要到达相应的类对象。类提供类似getAnnotation()
的方法。它还提供了检索表示特定类的方法和字段的其他对象的方法;并且可以以类似的方式查询这些对象以获取注释。
更新,关于问题中的更新:有些情况下,您没有访问类来自的文件系统的权限。你可以装载类,当你知道他们的名字,但你没有办法查看这些类居住的“地方”。这基本上破坏了您按预期使用反射的能力。
没有必要“证明”这一点,这仅仅是Java允许你在知道类名字的情况下装载它的结果,但却“隐藏”了那些类“从哪里来”的确切内容。
问题内容: 我得到了一些在程序中生成的Java字节码(即已编译的Java源代码)。现在,我想将此字节代码加载到当前运行的Java- VM中并运行特定功能。我不确定如何做到这一点,我对Java类加载器进行了一些研究,但没有找到直接的方法。 我找到了一个在硬盘上接收类文件的解决方案,但是我得到的字节码在字节数组中,我不想将其写入磁盘,而是直接使用它。 谢谢! 问题答案: 您需要编写一个自定义的类加载器
问题内容: 在整个类路径中搜索带注释的类的最佳方法是什么? 我正在做一个库,我想允许用户注释他们的类,所以当Web应用程序启动时,我需要扫描整个类路径以查找某些注释。 你知道执行此操作的库或Java工具吗? 编辑:我正在考虑类似Java EE 5 Web服务或EJB的新功能。你使用或注释类,系统在加载时会找到这些类,因此可以远程访问它们。 问题答案: 使用 API 组件提供程序,它从基本程序包扫描
我有一个注释@API,它分配给Java Spring中一个控制器中的所有路由,即RequestMapping。我想做的是,首先扫描一个包中用@controller注释的所有类,在扫描所有控制器类之后,我只想在这些控制器注释的类中扫描带有注释@API的方法。 我如何在Java中使用反射来实现这一点?
问题内容: 我正在用Java为具有特定脚本功能的领域特定语言编写解释器。我已经实现了解析器,现在需要做一个后端。为此,我正在考虑编写自己的解释器(使用抽象语法树或某些自定义字节码)或目标JVM(在运行时发出并执行Java字节码)。 对此领域有更多经验的人可以说针对JVM的方法可行吗?您建议使用哪些库来发出Java字节码? 问题答案: 这是使用ObjectWeb ASM(我推荐的一个库)构成的一个有
问题内容: 我的程序中有一个扫描仪,可以读取文件的一部分并将其格式化为HTML。当我读取文件时,我需要知道如何使扫描仪知道它在一行的末尾,然后开始写入下一行。 这是代码的相关部分,让我知道是否遗漏了什么: 我发现了有关,但是我仍然不知道如何确定何时到达终点。 问题答案: 如果只想使用Scanner,则需要创建一个临时字符串,将其实例化到数据网格的nextLine()(因此它仅返回跳过的行),并创建
问题内容: 我为Clojure添加了耐用性,最后我可以添加函数了。在Clojure中,使用调用方法(以及其他方法)将字节字节编译为类。这样,功能就是一流的。为了使这些持久化,我需要序列化和反序列化这些类。如何在不访问.class文件的情况下获取类的字节码? 如果我弄错了,请纠正我,但是使用代理程序需要产生一个单独的VM,并且该代理程序连接到第一个VM。我需要从同一台VM执行此操作。 仅使用Seri