假设我有这个注释
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Name
{
String value();
}
这将按如下方式使用
@Name("name1")
public static Foo foo = new Foo();
我在项目源文件中有多个这些。是否有一种相当简单的方法来搜索和收集@Name
之前的所有“foo”?
换句话说,我想编写一个返回包含这些的Set<Foo>
的方法。
感谢!!!
答案 0 :(得分:2)
我并不熟悉其他人建议的类路径扫描程序。它们似乎是一种强大的 - 如果不是理想的 - 解决方案。
如果您可以控制源,则可以使用注释处理。
创建一个注释处理器,它将创建一个带有静态成员MapClass
的类Map<String,Foo>
。每次注释处理器遇到@Name注释时,它都会将其添加到MapClass
的源代码中。完成处理注释后,它将具有与硬编码地图相同的效果。
注释处理在编译期间发生。如果项目中的某些类不是由您编译的。例如,如果其他人编译某些类并给你一个jar,那么它就不会那么容易了。但如果你编译了所有类,那么它应该不是问题。
要创建注释处理器,请展开AbstractProcessor
。您需要使用@ SupportedAnnotationTypes ( "Name" )
注释来注释您的类(确保名称是注释的完全限定名称。
覆盖process
方法。 process
有两个参数:annotations
和roundEnv
。 annotations
只是这个特定处理器支持的一组注释 - 在你的情况下应该是(Name)。 roundEnv
是一个有用的实用工具类。
迭代annotations
中的一个注释。使用roundEnv
与getElementsAnnotatedWith
。这应该为您提供带有@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在内部使用它!