如何搜索带注释类的整个类路径?

我正在创建一个库,希望允许用户注释他们的类,因此当Web应用程序启动时,我需要扫描整个类路径以查找某些注释。

我正在考虑类似于Java EE 5 Web服务或EJB的新功能。你用@WebService或@EJB注释你的类,系统会在加载时找到这些类,这样就可以远程访问它们。


当前回答

zapp有一篇精彩的评论,回答了所有这些问题:

new Reflections("my.package").getTypesAnnotatedWith(MyAnnotation.class)

其他回答

如果你想要一个真正轻量级(没有依赖,简单的API, 15 kb的jar文件)和非常快速的解决方案,可以看看https://github.com/rmuller/infomas-asl上的注释检测器

声明:我是作者。

您可以使用Java Pluggable Annotation Processing API编写注释处理器,该处理器将在编译过程中执行,并将收集所有注释类并构建索引文件以供运行时使用。

这是可能进行带注释类发现的最快方式,因为您不需要在运行时扫描类路径,这通常是非常缓慢的操作。此外,这种方法适用于任何类加载器,而不仅仅适用于运行时扫描程序通常支持的urlclassloader。

上述机制已经在ClassIndex库中实现。

使用@IndexAnnotated元注释注释您的自定义注释。这将在编译时创建一个索引文件:META-INF/annotations/com/test/YourCustomAnnotation,列出所有带注释的类。你可以在运行时通过执行以下命令访问索引:

ClassIndex.getAnnotated(com.test.YourCustomAnnotation.class)

如果你正在寻找一个替代反射,我想推荐Panda Utilities - AnnotationsScanner。这是一个基于反射库源代码的无Guava (Guava有~3MB, Panda Utilities有~200kb)扫描仪。

它还专门用于基于未来的搜索。如果你想扫描多次包含的源,或者甚至提供一个API,允许某人扫描当前的类路径,AnnotationsScannerProcess会缓存所有获取的类文件,所以它真的很快。

AnnotationsScanner使用的简单示例:

AnnotationsScanner scanner = AnnotationsScanner.createScanner()
        .includeSources(ExampleApplication.class)
        .build();

AnnotationsScannerProcess process = scanner.createWorker()
        .addDefaultProjectFilters("net.dzikoysk")
        .fetch();

Set<Class<?>> classes = process.createSelector()
        .selectTypesAnnotatedWith(AnnotationTest.class);

谷歌反射,如果你也想发现接口。

Spring ClassPathScanningCandidateComponentProvider没有发现接口。

Classloader API没有“枚举”方法,因为类加载是一个“按需”活动——在类路径中通常有数千个类,其中只有一小部分是需要的(目前仅rt.jar就有48MB !)

因此,即使您可以枚举所有的类,这也会非常耗费时间和内存。

简单的方法是在设置文件(xml或任何适合你的文件)中列出相关的类;如果您希望自动执行此操作,请将自己限制在一个JAR或一个类目录中。