クラスのいくつかのメンバー変数の注釈を知りたい、私はBeanInfo beanInfo = Introspector.getBeanInfo(User.class)
を使用してクラスを内省し、BeanInfo.getPropertyDescriptors()
を使用して特定のプロパティを見つけ、Class type = propertyDescriptor.getPropertyType()
を使用プロパティのClassを取得します。
しかし、注釈をメンバー変数に追加する方法がわかりませんか?
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
{
...
}
住所の注釈を取得したい:クラスAddressの注釈(@Entity、@Table、@Cache)ではなく@Column。それを達成する方法は?ありがとう。
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
誰もが注釈の取得に関する問題を説明していますが、問題は注釈の定義にあります。注釈定義に@Retention(RetentionPolicy.RUNTIME)
を追加する必要があります。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyAnnotation{
int id();
}
特定の注釈が存在するかどうかを知る必要がある場合。あなたはそうすることができます:
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);
}
他のアノテーションについても同様です...
私は誰かを助けることを願っています。
リフレクションを使用して、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
}
}
Getterメソッドで注釈を取得できます。
propertyDescriptor.getReadMethod().getDeclaredAnnotations();
プライベートフィールドの注釈を取得するのは悪い考えのように思えます...プロパティがフィールドに裏打ちされていない場合、または別の名前のフィールドに裏打ちされている場合はどうでしょうか?これらのケースを無視しても、プライベートなものを見ることで抽象化を壊しています。
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());
}
}
}
それが役に立てば幸い...
;-)
私のやり方
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));
}
}
}