java reflection annotations beaninfo

java - ¿Cómo obtener anotaciones de una variable miembro?



reflection annotations (8)

Quiero saber las anotaciones de una variable miembro de una clase, utilizo BeanInfo beanInfo = Introspector.getBeanInfo(User.class) para introspectar una clase, y uso BeanInfo.getPropertyDescriptors() , para encontrar una propiedad específica, y uso Class type = propertyDescriptor.getPropertyType() para obtener la clase de la propiedad.

¿Pero no sé cómo hacer que las anotaciones se agreguen a la variable miembro?

type.getAnnotations() y type.getDeclaredAnnotations() , pero ambos devuelven las anotaciones de la clase, no lo que yo quiero. Por ejemplo :

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

Quiero obtener la anotación de la dirección: @Column, no las anotaciones de Address de la clase (@Entity, @Table, @Cache). ¿Cómo lograrlo? Gracias.


Debes usar la reflexión para obtener todos los campos miembros de User clase User , recorrerlos y encontrar sus anotaciones

algo como esto:

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


Mi manera

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


O podrías intentar esto

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

Espero que esto ayude


Puedes obtener anotaciones en el método getter:

propertyDescriptor.getReadMethod().getDeclaredAnnotations();

Obtener las anotaciones de un campo privado parece una mala idea ... ¿y si la propiedad ni siquiera está respaldada por un campo, o está respaldada por un campo con un nombre diferente? Incluso ignorando esos casos, estás rompiendo la abstracción mirando cosas privadas.


Si necesita saber si una anotación específica está presente. Puedes hacerlo:

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

Y así sucesivamente para las otras anotaciones ...

Espero ayudar a alguien


Todo el mundo describe el problema con la obtención de anotaciones, pero el problema está en la definición de su anotación. Debería agregar a su definición de anotación una @Retention(RetentionPolicy.RUNTIME) :

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



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

Y una clase de prueba:

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

Espero eso ayude...

;-)