如何在类属性上添加批注,以及如何迭代属性



我想在我的类属性上添加注释,然后迭代我的所有属性,并能够查找注释。

例如,我有一个这样的类:

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()的内容。

最新更新