Как получить аннотации переменной-члена? - PullRequest
55 голосов
/ 15 декабря 2010

Я хочу знать аннотации некоторых переменных-членов класса, я использую BeanInfo beanInfo = Introspector.getBeanInfo(User.class), чтобы проанализировать класс, и BeanInfo.getPropertyDescriptors(), чтобы найти конкретное свойство, и использовать Class type = propertyDescriptor.getPropertyType(), чтобы получить класс свойства.

Но я не знаю, как добавить аннотации к переменной-члену?

Я пробовал type.getAnnotations() и type.getDeclaredAnnotations(), но оба возвращают аннотации класса, а не то, что я хочу.Например:

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 
{
  ...
}

Я хочу получить аннотацию адреса: @Column, а не аннотации класса Address (@Entity, @Table, @Cache).Как этого добиться?Спасибо.

Ответы [ 8 ]

79 голосов
/ 08 сентября 2012

Все описывают проблему с получением аннотаций, но проблема заключается в определении вашей аннотации.Вы должны добавить к своему определению аннотации a @Retention(RetentionPolicy.RUNTIME):

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyAnnotation{
    int id();
}
72 голосов
/ 15 декабря 2010
for(Field field : cls.getDeclaredFields()){
  Class type = field.getType();
  String name = field.getName();
  Annotation[] annotations = field.getDeclaredAnnotations();
}

Смотри также: http://docs.oracle.com/javase/tutorial/reflect/class/classMembers.html

12 голосов
/ 09 мая 2013

Если вам нужно знать, присутствует ли конкретная аннотация. Вы можете сделать это:

    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);

        }

И так далее для других аннотаций ...

Я надеюсь помочь кому-нибудь.

8 голосов
/ 15 декабря 2010

Вы должны использовать отражение, чтобы получить все поля-члены класса User, перебрать их и найти их аннотации

примерно так:

public void getAnnotations(Class clazz){
    for(Field field : clazz.getDeclaredFields()){
        Class type = field.getType();
        String name = field.getName();
        field.getDeclaredAnnotations(); //do something to these
    }
}
5 голосов
/ 15 декабря 2010

Вы можете получить аннотации по методу получения:

propertyDescriptor.getReadMethod().getDeclaredAnnotations();

Получение аннотаций частного поля кажется плохой идеей ... что, если свойство даже не поддерживается полем или имеет поле с другим именем? Даже игнорируя эти случаи, вы нарушаете абстракцию, глядя на личные вещи.

4 голосов
/ 24 декабря 2010
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(){

    }
}

И тестовый класс:

    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());
        }
    }

}

Надеюсь, это поможет ...

; -)

1 голос
/ 15 декабря 2015

Мой путь

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 голосов
/ 07 марта 2013

Или вы можете попробовать это

try {
    BeanInfo bi = Introspector.getBeanInfo(User.getClass());
    PropertyDescriptor[] properties = bi.getPropertyDescriptors();
    for(PropertyDescriptor property : properties) {
        //One way
        for(Annotation annotation : property.getAnnotations()){
            if(annotation instanceof Column) {
                String string = annotation.name();
            }
        }
        //Other way
        Annotation annotation = property.getAnnotation(Column.class);
        String string = annotation.name();
    }
}catch (IntrospectonException ie) {
    ie.printStackTrace();
}

Надеюсь, это поможет.

...