[英]How to get annotations of a member variable?
I want to know a class's some member variable's annotations , I use BeanInfo beanInfo = Introspector.getBeanInfo(User.class)
to introspect a class , and use BeanInfo.getPropertyDescriptors()
, to find specific property , and use Class type = propertyDescriptor.getPropertyType()
to get the property's Class . 我想知道一个类的一些成员变量的注释,我使用BeanInfo beanInfo = Introspector.getBeanInfo(User.class)
来内省一个类,并使用BeanInfo.getPropertyDescriptors()
来查找特定属性,并使用Class type = propertyDescriptor.getPropertyType()
获得属性的类。
But I don't know how to get the annotations added to the member variable ? 但我不知道如何将注释添加到成员变量中?
I tried type.getAnnotations()
, and type.getDeclaredAnnotations()
, but both return the Class's annotations , not what I want . 我尝试了type.getAnnotations()
和type.getDeclaredAnnotations()
,但都返回了Class的注释,而不是我想要的。 For example : 例如 :
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
{
...
}
I want to get the address's annotation : @Column , not class Address's annotations (@Entity , @Table , @Cache) . 我想得到地址的注释:@Column,而不是类地址的注释(@ Entity,@ Table,@ Cache)。 How to achieve it ? 怎么实现呢? Thanks. 谢谢。
Everybody describes issue with getting annotations, but the problem is in definition of your annotation. 每个人都描述了获取注释的问题,但问题在于注释的定义。 You should to add to your annotation definition a @Retention(RetentionPolicy.RUNTIME)
: 您应该在注释定义中添加@Retention(RetentionPolicy.RUNTIME)
:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyAnnotation{
int id();
}
for(Field field : cls.getDeclaredFields()){
Class type = field.getType();
String name = field.getName();
Annotation[] annotations = field.getDeclaredAnnotations();
}
See also: http://docs.oracle.com/javase/tutorial/reflect/class/classMembers.html 另见: http : //docs.oracle.com/javase/tutorial/reflect/class/classMembers.html
If you need know if a annotation specific is present. 如果您需要知道是否存在特定注释。 You can do so: 你可以这样做:
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);
}
And so on for the other annotations... 等等其他注释......
I hope help someone. 我希望能帮助别人。
You have to use reflection to get all the member fields of User
class, iterate through them and find their annotations 您必须使用反射来获取User
类的所有成员字段,迭代它们并找到它们的注释
something like this: 这样的事情:
public void getAnnotations(Class clazz){
for(Field field : clazz.getDeclaredFields()){
Class type = field.getType();
String name = field.getName();
field.getDeclaredAnnotations(); //do something to these
}
}
You can get annotations on the getter method: 您可以获取getter方法的注释:
propertyDescriptor.getReadMethod().getDeclaredAnnotations();
Getting the annotations of a private field seems like a bad idea... what if the property isn't even backed by a field, or is backed by a field with a different name? 获取私有字段的注释似乎是个坏主意......如果属性甚至没有字段支持,或者由具有不同名称的字段支持,该怎么办? Even ignoring those cases, you're breaking abstraction by looking at private stuff. 即使忽略这些情况,你也会通过查看私人内容来打破抽象。
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(){
}
}
And a testing class: 还有一个测试类:
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());
}
}
}
Hope it helps... 希望能帮助到你...
;-) ;-)
My way 我的方式
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));
}
}
}
Or you could try this 或者你可以试试这个
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();
}
Hope this will help. 希望这会有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.