搜索某些注释类型的所有实例

时间:2012-04-01 00:13:56

标签: java annotations

假设我有这个注释

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface  Name 
{
    String value();
}

这将按如下方式使用

@Name("name1")
public static Foo foo = new Foo();

我在项目源文件中有多个这些。是否有一种相当简单的方法来搜索和收集@Name之前的所有“foo”? 换句话说,我想编写一个返回包含这些的Set<Foo>的方法。

感谢!!!

4 个答案:

答案 0 :(得分:2)

我并不熟悉其他人建议的类路径扫描程序。它们似乎是一种强大的 - 如果不是理想的 - 解决方案。

如果您可以控制源,则可以使用注释处理。

创建一个注释处理器,它将创建一个带有静态成员MapClass的类Map<String,Foo>。每次注释处理器遇到@Name注释时,它都会将其添加到MapClass的源代码中。完成处理注释后,它将具有与硬编码地图相同的效果。

注释处理在编译期间发生。如果项目中的某些类不是由您编译的。例如,如果其他人编译某些类并给你一个jar,那么它就不会那么容易了。但如果你编译了所有类,那么它应该不是问题。

要创建注释处理器,请展开AbstractProcessor。您需要使用@ SupportedAnnotationTypes ( "Name" )注释来注释您的类(确保名称是注释的完全限定名称。

覆盖process方法。 process有两个参数:annotationsroundEnvannotations只是这个特定处理器支持的一组注释 - 在你的情况下应该是(Name)。 roundEnv是一个有用的实用工具类。

迭代annotations中的一个注释。使用roundEnvgetElementsAnnotatedWith。这应该为您提供带有@Name注释的所有元素的集合。

AbstractProcessor有另一个实用程序成员 - processingEnv。使用getFiler方法createSourceFile

然后你必须稍微修改你的编译。您必须在其他类之前单独编译处理器。在编译处理器并编译其他类之后,必须告诉编译器有关处理器的信息。如果您使用的是命令行,则可以添加-processorpath /path/to/processor/class[es]-processor qualified.name.of.processor

这种方法相对于类路径扫描器的优点是一切都在编译时发生。因此,例如,如果您不小心将@Name注释添加到Bar元素,那么您可以让处理器抛出编译时错误(如果您希望处理器可以忽略它)。然后您可以在产品发布之前修复它。使用类路径扫描程序时,抛出的任何错误都是运行时错误 - 用户将看到错误。

这种方法的缺点是一切都在编译时发生。这使得向项目动态添加类更加困难。

答案 1 :(得分:1)

您需要的是Classpath扫描程序。我已经使用Metapossum Scanner(因为它在mvn repo中而胜出)来扫描带注释的类,但我不认为它会扫描带注释的字段。

我调查的另一个选项是Reflections。我没有使用过Reflections,只研究过它。该文档具有getFieldsAnnotatedWith查询,看起来就像您需要的那样。

预先警告,Classpath扫描仪是懒散的,并且在Classpath中拥有的越多越好。

答案 2 :(得分:0)

不是真的(不是来自代码)。 一个解决方案是将它们全部放在一个类中,然后迭代该类的Field s(getFields())并检查Annotation s(getAnnotation())< / p>

答案 3 :(得分:0)

您可能需要查看Scannotation!它可以解决你的问题!!!

  

Scannotation是一个Java库,它从一组.class文件创建注释数据库。这个数据库实际上只是一组映射,用于索引使用的注释以及使用它们的类。

PS。:VRaptor framework在内部使用它!