web-dev-qa-db-de.com

Wie bekomme ich Anmerkungen zu einer Membervariablen?

Ich möchte die Anmerkungen einiger Klassenvariablen einer Klasse kennenlernen, ich benutze BeanInfo beanInfo = Introspector.getBeanInfo(User.class), um eine Klasse zu untersuchen, und BeanInfo.getPropertyDescriptors(), um eine bestimmte Eigenschaft zu finden, und Klasse type = propertyDescriptor.getPropertyType(), um die Klasse der Eigenschaft abzurufen.

Aber ich weiß nicht, wie man die Anmerkungen zur Mitgliedervariable hinzufügt?

Ich habe type.getAnnotations() und type.getDeclaredAnnotations() versucht, aber beide geben die Anmerkungen der Klasse zurück, nicht das, was ich will. Zum Beispiel :

class User 
{
  @Id
  private Long id;

  @Column(name="ADDRESS_ID")
  private Address address;

  // getters , setters
}

@Entity
@Table(name = "Address")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
class Address 
{
  ...
}

Ich möchte die Annotation der Adresse erhalten: @Column, nicht die Annotationen der Klasse Address (@Entity, @Table, @Cache). Wie kann ich das erreichen? Vielen Dank.

52
smallufo
for(Field field : cls.getDeclaredFields()){
  Class type = field.getType();
  String name = field.getName();
  Annotation[] annotations = field.getDeclaredAnnotations();
}

Siehe auch: http://docs.Oracle.com/javase/tutorial/reflect/class/classMembers.html

67

Jeder beschreibt ein Problem mit dem Erhalten von Anmerkungen, aber das Problem liegt in der Definition Ihrer Anmerkungen. Sie sollten Ihrer Anmerkungsdefinition eine @Retention(RetentionPolicy.RUNTIME) hinzufügen:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyAnnotation{
    int id();
}
75
Saturnim

Wenn Sie wissen müssen, ob eine bestimmte Anmerkung vorhanden ist. Das kannst du tun:

    Field[] fieldList = obj.getClass().getDeclaredFields();

        boolean isAnnotationNotNull, isAnnotationSize, isAnnotationNotEmpty;

        for (Field field : fieldList) {

            //Return the boolean value
            isAnnotationNotNull = field.isAnnotationPresent(NotNull.class);
            isAnnotationSize = field.isAnnotationPresent(Size.class);
            isAnnotationNotEmpty = field.isAnnotationPresent(NotEmpty.class);

        }

Und so weiter für die anderen Anmerkungen ...

Ich hoffe jemandem helfen.

12

Sie müssen die Reflektion verwenden, um alle Mitgliederfelder der Klasse User zu erhalten, durchlaufen und ihre Anmerkungen finden

etwas wie das:

public void getAnnotations(Class clazz){
    for(Field field : clazz.getDeclaredFields()){
        Class type = field.getType();
        String name = field.getName();
        field.getDeclaredAnnotations(); //do something to these
    }
}
8
mkoryak

Sie können Anmerkungen zur Getter-Methode erhalten:

propertyDescriptor.getReadMethod().getDeclaredAnnotations();

Die Annotationen eines privaten Felds zu erhalten, scheint eine schlechte Idee zu sein. Was passiert, wenn die Eigenschaft nicht durch ein Feld oder durch ein Feld mit einem anderen Namen gesichert wird? Selbst wenn Sie diese Fälle ignorieren, brechen Sie die Abstraktion, indem Sie private Dinge betrachten.

5
package be.fery.annotation;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.PrePersist;

@Entity
public class User {
    @Id
    private Long id;

    @Column(name = "ADDRESS_ID")
    private Address address;

    @PrePersist
    public void doStuff(){

    }
}

Und eine Testklasse:

    package be.fery.annotation;

import Java.lang.annotation.Annotation;
import Java.lang.reflect.Field;
import Java.lang.reflect.Method;

public class AnnotationIntrospector {

    public AnnotationIntrospector() {
        super();
    }

    public Annotation[] findClassAnnotation(Class<?> clazz) {
        return clazz.getAnnotations();
    }

    public Annotation[] findMethodAnnotation(Class<?> clazz, String methodName) {

        Annotation[] annotations = null;
        try {
            Class<?>[] params = null;
            Method method = clazz.getDeclaredMethod(methodName, params);
            if (method != null) {
                annotations = method.getAnnotations();
            }
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return annotations;
    }

    public Annotation[] findFieldAnnotation(Class<?> clazz, String fieldName) {
        Annotation[] annotations = null;
        try {
            Field field = clazz.getDeclaredField(fieldName);
            if (field != null) {
                annotations = field.getAnnotations();
            }
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        return annotations;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        AnnotationIntrospector ai = new AnnotationIntrospector();
        Annotation[] annotations;
        Class<User> userClass = User.class;
        String methodDoStuff = "doStuff";
        String fieldId = "id";
        String fieldAddress = "address";

        // Find class annotations
        annotations = ai.findClassAnnotation(be.fery.annotation.User.class);
        System.out.println("Annotation on class '" + userClass.getName()
                + "' are:");
        showAnnotations(annotations);

        // Find method annotations
        annotations = ai.findMethodAnnotation(User.class, methodDoStuff);
        System.out.println("Annotation on method '" + methodDoStuff + "' are:");
        showAnnotations(annotations);

        // Find field annotations
        annotations = ai.findFieldAnnotation(User.class, fieldId);
        System.out.println("Annotation on field '" + fieldId + "' are:");
        showAnnotations(annotations);

        annotations = ai.findFieldAnnotation(User.class, fieldAddress);
        System.out.println("Annotation on field '" + fieldAddress + "' are:");
        showAnnotations(annotations);

    }

    public static void showAnnotations(Annotation[] ann) {
        if (ann == null)
            return;
        for (Annotation a : ann) {
            System.out.println(a.toString());
        }
    }

}

Ich hoffe es hilft...

;-)

3
Philippe Fery

Auf meine Art

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import Java.beans.BeanInfo;
import Java.beans.Introspector;
import Java.beans.PropertyDescriptor;

public class ReadAnnotation {
    private static final Logger LOGGER = LoggerFactory.getLogger(ReadAnnotation.class);

    public static boolean hasIgnoreAnnotation(String fieldName, Class entity) throws NoSuchFieldException {
        return entity.getDeclaredField(fieldName).isAnnotationPresent(IgnoreAnnotation.class);
    }

    public static boolean isSkip(PropertyDescriptor propertyDescriptor, Class entity) {
        boolean isIgnoreField;
        try {
            isIgnoreField = hasIgnoreAnnotation(propertyDescriptor.getName(), entity);
        } catch (NoSuchFieldException e) {
            LOGGER.error("Can not check IgnoreAnnotation", e);
            isIgnoreField = true;
        }
        return isIgnoreField;
    }

    public void testIsSkip() throws Exception {
        Class<TestClass> entity = TestClass.class;
        BeanInfo beanInfo = Introspector.getBeanInfo(entity);

        for (PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors()) {
            System.out.printf("Field %s, has annotation %b", propertyDescriptor.getName(),  isSkip(propertyDescriptor, entity));
        }
    }

}
0
Gleb Belyaev