我想获得应用程序中使用@Custom
注释注释的完整类列表。这项行动的最佳机制是什么?
PS。例如,JAX-RS实现如何查找所有使用@Path
注释的类?我想使用相同的机制。
答案 0 :(得分:23)
通常这是使用称为类路径扫描的过程完成的。通常,类加载器不允许扫描类路径上的所有类。但通常唯一使用的类加载器是UrlClassLoader
,我们可以从中检索目录和jar文件列表(参见getURLs)并逐个打开它们以列出可用的类。
此方法由Scannotation和Reflections等库实现。
另一种方法是使用Java Pluggable Annotation Processing API编写注释处理器,它将在编译时收集所有带注释的类,并构建索引文件以供运行时使用。
上述机制在ClassIndex库中实现。
使用类路径扫描通常比编译时索引慢两个数量级。请参阅this benchmark。
答案 1 :(得分:10)
我知道这是一个老问题,但我在自己的类路径扫描搜索中遇到了它并找到了另一个好的答案,所以我在这里添加它。
Google Guava有一个ClassPath对象提供“尽力而为”的类路径扫描(实际上是所有类路径扫描实用程序提供的)。由于Guava是一个广泛采用的,经过精心维护的实用程序库,对于(a)已经在使用Guava的项目,或者(b)需要一个可以依赖的类库路径扫描的稳定库,这是一个很好的选择。
答案 2 :(得分:3)
你应该看看Scannotation。
答案 3 :(得分:3)
你可以试试我的图书馆FastClasspathScanner:
List<String> classNames = new FastClassPathScanner("com.mypackage")
.scan()
.getNamesOfClassesWithAnnotation(Custom.class);
答案 4 :(得分:2)
正如您现在可能知道的那样,Java无法枚举每个包中的所有包或类。所以你必须以“艰难”的方式去做。选项:
使用grep
之类的工具搜索注释。优点:快速,简单。缺点:可能会返回误报(如注释被注释掉的类)。
编译代码并使用javap
处理结果。这适用于字节码级别[*]。它可以为您提供准确的结果,但javap
的输出并不适用于自动处理。
使用像ASM这样的字节码库。不适合胆小的人,但它允许您访问与注释相关的其他数据(如实现的接口,字段等)。
最后一个选项:Eclipse使用自己的Java编译器,可以从Java代码构建AST(即使代码不能编译)。优于ASM:您可以免费获得Java代码模型。使某些操作更简单。但是,没有那么容易设置。 See my blog for an example
[*]:注释必须Retention.RUNTIME
才能生效。
答案 5 :(得分:2)
classindex是一个编译时注释扫描库,使用注释处理器实现。
答案 6 :(得分:0)
在源代码中在IDE中运行一个find,如果你试图在编译的类上执行此操作,你可以为它们添加一个方法来支持它,即使你反编译了类我不认为注释或注释会出现
答案 7 :(得分:0)
最简单的方法是使用IDE as Jesus suggested。
但你也可以
注意:所有这些都很棘手。 AspectJ解决方案应该是最简单的。