Java 如何构建用自定义注释注释的类列表?
我想获得应用程序中使用Java 如何构建用自定义注释注释的类列表?,java,annotations,Java,Annotations,我想获得应用程序中使用@Custom注释注释的类的完整列表。这种操作的最佳机制是什么 例如,JAX-RS实现如何找到用@Path注释的所有类?我希望使用相同的机制。在源代码上的IDE中运行查找,如果您试图在已编译的类上执行此操作,则必须向它们添加一个方法来支持此操作,即使您反编译了我认为不会显示注释或注释的类。您现在可能已经知道,Java无法枚举所有包或每个包中的类。所以你必须用“艰难”的方式去做。选项: 使用类似于grep的工具搜索注释。优点:快速,简单。缺点:可能返回误报(例如注释被注释掉的
@Custom
注释注释的类的完整列表。这种操作的最佳机制是什么
例如,JAX-RS实现如何找到用
@Path
注释的所有类?我希望使用相同的机制。在源代码上的IDE中运行查找,如果您试图在已编译的类上执行此操作,则必须向它们添加一个方法来支持此操作,即使您反编译了我认为不会显示注释或注释的类。您现在可能已经知道,Java无法枚举所有包或每个包中的类。所以你必须用“艰难”的方式去做。选项:
grep
的工具搜索注释。优点:快速,简单。缺点:可能返回误报(例如注释被注释掉的类)javap
处理结果。它在字节码级别[*]上工作。它提供了准确的结果,但是javap
的输出实际上并不用于自动处理[*]:注释必须具有
保留。运行时才能起作用。最简单的方法是使用IDE
但你也可以
- 编写一个日志,记录注释的所有引用
- 编写一个AspectJ方面(我知道,警告可能不是您想要的,但AspectJ中没有信息)
- 用于检查注释的字节码
- 用于检查注释的源代码
注意:所有这些都很棘手。AspectJ解决方案应该是最简单的。您应该看看 通常使用称为类路径扫描的过程来完成。通常,类装入器不允许扫描类路径上的所有类。但通常唯一使用的类加载器是UrlClassLoader
,我们可以从中检索目录和jar文件列表(请参阅),并逐个打开它们以列出可用的类
这种方法由像和这样的库实现
另一种方法是编写注释处理器,该处理器将在编译时收集所有注释类,并构建索引文件供运行时使用
上述机制在库中实现
使用类路径扫描通常比编译时索引慢两个数量级。请参阅。我知道这是一个老问题,但我在自己的类路径扫描搜索中遇到了它,并找到了另一个很好的答案,所以我将其添加到这里
有一个提供“尽力而为”类路径扫描的对象(实际上,这是所有类路径扫描实用程序提供的)。由于Guava是一个被广泛采用的、精心维护的实用程序库,对于(a)已经在使用Guava的项目,或者(b)需要一个稳定的库来进行类路径扫描的项目,这是一个很好的选择。是一个编译时注释扫描库,使用批注处理器实现。您可以尝试我的库:
List classNames=新的FastClassPathScanner(“com.mypackage”)
.scan()
.getNamesofClassswithanNotation(Custom.class);
您想在源代码(.java)或编译代码(.class)中搜索吗?不,我不使用任何IDE。我只对JAR中的编译代码感兴趣。@Brian是的,如果注释的@Retention
是RUNTIME
。。。如果它们是用@Retention(RUNTIME)
First Option=arggghh定义的。所有其他:+1您的JAX-RS实现使用了哪些选项(例如,泽西岛)来查找所有@Path
-注释类?是否愿意为您的说法提供证据,证明没有办法?特别是考虑到我在回答中链接到的图书馆,这是正确的;请注意,运行时的类路径可能不同于编译时的类路径。因此类路径扫描是脆弱的。当代码在应用程序服务器中运行或使用自定义类加载器时,检查系统属性java.class.path
可能会导致错误的结果。并非所有类加载器都允许检查类从何处加载的路径。因此,我的主张是:Java没有API来实现这一点。你必须求助于某种黑客手段。我只想指出,你实际上可以在运行时获得这些信息,但你需要使用反射来在你正在使用的类加载器上公开“classes”属性。这是不推荐的,在较新版本的Java中可能会中断(不能保证在下一版本中会有私有方法)。更多信息请访问
List<String> classNames = new FastClassPathScanner("com.mypackage")
.scan()
.getNamesOfClassesWithAnnotation(Custom.class);