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

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

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


当前回答

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

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

其他回答

Spring有一个AnnotatedTypeScanner类。 这个类内部使用

ClassPathScanningCandidateComponentProvider

该类具有实际扫描类路径资源的代码。它通过使用运行时可用的类元数据来实现这一点。

可以简单地扩展这个类或使用相同的类进行扫描。下面是构造函数定义。

/**
     * Creates a new {@link AnnotatedTypeScanner} for the given annotation types.
     * 
     * @param considerInterfaces whether to consider interfaces as well.
     * @param annotationTypes the annotations to scan for.
     */
    public AnnotatedTypeScanner(boolean considerInterfaces, Class<? extends Annotation>... annotationTypes) {

        this.annotationTypess = Arrays.asList(annotationTypes);
        this.considerInterfaces = considerInterfaces;
    }

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

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

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

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

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

使用org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider

API

从基本包扫描类路径的组件提供程序。然后,它对结果类应用排除和包括过滤器来查找候选类。

ClassPathScanningCandidateComponentProvider scanner =
new ClassPathScanningCandidateComponentProvider(<DO_YOU_WANT_TO_USE_DEFALT_FILTER>);

scanner.addIncludeFilter(new AnnotationTypeFilter(<TYPE_YOUR_ANNOTATION_HERE>.class));

for (BeanDefinition bd : scanner.findCandidateComponents(<TYPE_YOUR_BASE_PACKAGE_HERE>))
    System.out.println(bd.getBeanClassName());

另一个解决方案是朗玛莫的倒影。

快速回顾一下:

如果您正在使用Spring,那么Spring解决方案是最好的选择。否则就是很大的依赖。 直接使用ASM有点麻烦。 直接使用Java Assist也很笨拙。 注释超轻,方便。还没有专家集成。 Reflections索引所有东西,而且非常快。