Java 如何构建用我的自定义注释注释的类列表?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4107498/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to build a list of classes annotated with my custom annotation?
提问by yegor256
I want to get a complete list of classes in the application which are annotated with @Custom
annotation. What is the best mechanism for this operation?
我想获得应用程序中用@Custom
注释注释的类的完整列表。此操作的最佳机制是什么?
ps. For example, how JAX-RS implementations find all classes that are annotated with @Path
? I would like to use the same mechanism.
附:例如,JAX-RS 实现如何找到所有用@Path
? 我想使用相同的机制。
采纳答案by S?awek
Usually this is done using the process called classpath scanning. In general class loaders do not allow for scanning through all the classes on the classpath. But usually the only used class loader is UrlClassLoader
from which we can retrieve the list of directories and jar files (see getURLs) and open them one by one to list available classes.
通常这是使用称为类路径扫描的过程完成的。一般来说,类加载器不允许扫描类路径上的所有类。但通常唯一使用的类加载器是UrlClassLoader
我们可以从中检索目录和 jar 文件列表(参见getURLs)并一一打开它们以列出可用类的加载器。
This approach is implemented by libraries like Scannotationand Reflections.
这种方法由Scannotation和Reflections等库实现。
Another approach is to use Java Pluggable Annotation Processing APIto write annotation processor which will collect all annotated classes at compile time and build the index file for runtime use.
另一种方法是使用Java Pluggable Annotation Processing API编写 annotation processor,它将在编译时收集所有带注释的类并构建索引文件以供运行时使用。
The above mechanism is implemented in ClassIndexlibrary.
上述机制是在ClassIndex库中实现的。
Using classpath scanning is usually two orders of magnitude slower than compile-time indexing. See this benchmark.
使用类路径扫描通常比编译时索引慢两个数量级。请参阅此基准。
回答by Keibosh
Run a find in your IDE on the source, If you trying to do this on compiled classes you would have add a method to them to support this, even if you decompiled the classes I do not think annotations or comments would show up.
在源代码的 IDE 中运行查找,如果您尝试在已编译的类上执行此操作,您将向它们添加一个方法来支持这一点,即使您反编译了这些类,我认为注释或注释不会出现。
回答by Aaron Digulla
As you probably know by now, Java has no way to enumerate all packages or the classes in each package. So you have to do it the "hard" way. Options:
您现在可能已经知道,Java 无法枚举所有包或每个包中的类。所以你必须以“艰难”的方式去做。选项:
Use a tool like
grep
to search for the annotation. Advantage: Fast, simple. Drawbacks: Might return false positives (like classes where the annotation is commented out).Compile the code and process the result with
javap
. That works on the bytecode level[*]. It gives you accurate results but the output ofjavap
isn't really meant for automatic processing.Use a bytecode library like ASM. Not for the faint of heart but it allows you to access other data as well (like implemented interfaces, fields, etc) in relation to the annotation.
Last option: Eclipse uses its own Java compiler which can build an AST from Java code (even if the code doesn't compile). Advantage over ASM: You get a model for Java code for free. Makes certain operations more simple. No so easy to set up, though. See my blog for an example.
使用类似的工具
grep
来搜索注释。优点:快速、简单。缺点:可能会返回误报(例如注释被注释掉的类)。编译代码并使用
javap
. 这适用于字节码级别[*]。它为您提供准确的结果,但 的输出javap
并不真正用于自动处理。使用像ASM这样的字节码库。不适合胆小的人,但它允许您访问与注释相关的其他数据(如实现的接口、字段等)。
最后一个选择:Eclipse 使用它自己的 Java 编译器,它可以从 Java 代码构建一个 AST(即使代码不能编译)。相对于 ASM 的优势:您可以免费获得 Java 代码模型。使某些操作更加简单。但是,设置起来并不容易。有关示例,请参阅我的博客。
[*]: The annotation must have Retention.RUNTIME
for this to work.
[*]:注释必须具有Retention.RUNTIME
此功能。
回答by Sean Patrick Floyd
The easiest way would be to use an IDE as Jesus suggested.
最简单的方法是使用耶稣建议的 IDE 。
But you could also
但你也可以
- write an annotation processorthat logs all occurrences of the annotation
- write an AspectJ aspect and declare a warning for this annotation(I know, warning is probably not what you want, but there is no INFO in AspectJ)
- use ASMto check the byte code for the annotation
- use a Source Parserto check the source code for the annotation
- 编写一个注释处理器,记录所有出现的注释
- 编写一个 AspectJ 方面并为此注释声明警告(我知道,警告可能不是您想要的,但 AspectJ 中没有 INFO)
- 使用ASM检查注解的字节码
- 使用Source Parser检查注释的源代码
Beware: All of these are tricky. The AspectJ solution should be the simplest.
当心:所有这些都很棘手。AspectJ 解决方案应该是最简单的。
回答by keuleJ
You should take a look at Scannotation.
你应该看看Scannotation。
回答by sigpwned
I know this is an old question, but I ran across it in my own search for classpath scanning and found another good answer, so I'm adding it here.
我知道这是一个老问题,但我在自己搜索类路径扫描时遇到了它并找到了另一个很好的答案,所以我在这里添加它。
Google Guavahas a ClassPathobject that provides "best effort" classpath scanning (which is all any classpath scanning utility offers, really). Since Guava is a widely-adopted, carefully-maintained utility library, this is a great option for projects that either (a) are already using Guava, or (b) need a stable library they can rely on for classpath scanning.
Google Guava有一个ClassPath对象,它提供“尽力而为”的类路径扫描(这是所有类路径扫描实用程序提供的,真的)。由于 Guava 是一个被广泛采用、精心维护的实用程序库,因此对于 (a) 已经在使用 Guava 或 (b) 需要一个稳定的库来进行类路径扫描的项目来说,这是一个很好的选择。
回答by snorbi
classindexis a compile-time annotation scanning library, implemented using an annotation processor.
classindex是一个编译时注释扫描库,使用注释处理器实现。
回答by Luke Hutchison
You could try my library FastClasspathScanner:
你可以试试我的库FastClasspathScanner:
List<String> classNames = new FastClassPathScanner("com.mypackage")
.scan()
.getNamesOfClassesWithAnnotation(Custom.class);