我想在我的类属性上添加注释,然后迭代我的所有属性,并能够查找注释。
例如,我有一个这样的类:
public class User {
@Annotation1
private int id;
@Annotation2
private String name;
private int age;
// getters and setters
}
现在,我希望能够遍历我的属性,并能够知道属性上的注释(如果有的话(。
我想知道如何仅使用 java 来做到这一点,但也很好奇使用 spring、番石榴或谷歌 guice 是否会让这件事变得更容易(如果他们有任何助手来更轻松地做到这一点(。
下面是一个利用(几乎没有维护的(bean introspection 框架的示例。这是一个全 Java 解决方案,您可以扩展以满足您的需求。
public class BeanProcessor {
public static void main(String[] args) {
try {
final Class<?> beanClazz = BBean.class;
BeanInfo info = Introspector.getBeanInfo(beanClazz);
PropertyDescriptor[] propertyInfo = info.getPropertyDescriptors();
for (final PropertyDescriptor descriptor : propertyInfo) {
try {
final Field field = beanClazz.getDeclaredField(descriptor
.getName());
System.out.println(field);
for (final Annotation annotation : field
.getDeclaredAnnotations()) {
System.out.println("Annotation: " + annotation);
}
} catch (final NoSuchFieldException nsfe) {
// ignore these
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
以下是创建自己的注释的方法
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Annotation1 {
public String name();
public String value();
}
定义注释后,使用问题中提到的注释,您可以使用以下反射方法来获取注释类详细信息
Class aClass = User.class;
Annotation[] annotations = aClass.getAnnotations();
for(Annotation annotation : annotations){
if(annotation instanceof Annotation1){
Annotation1 myAnnotation = (Annotation1) annotation;
System.out.println("name: " + myAnnotation.name());
System.out.println("value: " + myAnnotation.value());
}
}
我创建了下面的方法,该方法创建了一个类中所有字段的流,并且它是具有特定注释的超类。还有其他方法可以做到这一点。但我认为这个解决方案非常容易重用和实用,因为当你需要了解这些字段时,通常是在每个字段上执行操作。而流正是您所需要的。
public static Stream<Field> getAnnotatedFieldStream(Class<?> theClass, Class<? extends Annotation> annotationType) {
Class<?> classOrSuperClass = theClass;
Stream<Field> stream = Stream.empty();
while(classOrSuperClass != Object.class) {
stream = Stream.concat(stream, Stream.of(classOrSuperClass.getDeclaredFields()));
classOrSuperClass = classOrSuperClass.getSuperclass();
}
return stream.filter(f -> f.isAnnotationPresent(annotationType));
}
您将使用反射来获取类的字段,然后在每个字段上调用类似getAnnotations()
的内容。