2010-12-14 30 views
6

Tôi tự hỏi liệu có cách nào để có thể nhận thông tin chú thích của một lớp khi chạy không? Vì tôi muốn nhận được các thuộc tính được chú thích một cách cẩn thận.lấy thông tin chú thích khi chạy

Ví dụ:

class TestMain { 
    @Field(
      store = Store.NO) 
    private String name; 
    private String password; 
    @Field(
      store = Store.YES) 
    private int  age; 

    //..........getter and setter 
} 

Các chú thích xuất phát từ hibernate-tìm kiếm, và bây giờ những gì tôi muốn là được mà tài sản của "TestMain" được chú thích như một 'trường' (trong ví dụ này, chúng là [tên, tuổi]) và được lưu trữ (lưu trữ = store.yes) '(trong ví dụ, chúng là [tuổi]) khi chạy.

Bất kỳ ý tưởng nào?

Cập nhật:

public class FieldUtil { 
public static List<String> getAllFieldsByClass(Class<?> clazz) { 
    Field[] fields = clazz.getDeclaredFields(); 
    ArrayList<String> fieldList = new ArrayList<String>(); 
    ArrayList<String> storedList=new ArrayList<String>(); 
    String tmp; 
    for (int i = 0; i < fields.length; i++) { 
     Field fi = fields[i]; 
     tmp = fi.getName(); 
     if (tmp.equalsIgnoreCase("serialVersionUID")) 
      continue; 
     if (fi.isAnnotationPresent(org.hibernate.search.annotations.Field.class)) { 
      //it is a "field",add it to list. 
      fieldList.add(tmp); 

      //make sure if it is stored also 
      Annotation[] ans = fi.getAnnotations(); 
      for (Annotation an : ans) { 
       //here,how to get the detail annotation information 
       //I print the value of an,it is something like this: 
       //@org.hibernate.search.annotations.Field(termVector=NO, index=UN_TOKENIZED, store=NO, name=, [email protected](value=1.0), [email protected](impl=void, definition=), [email protected](impl=void, params=[])) 

       //how to get the parameter value of this an? using the string method?split? 
      } 
     } 

    } 
    return fieldList; 
} 

}

+0

Bạn có thể nhận được phản hồi nhanh hơn nếu bạn thêm thẻ bằng ngôn ngữ lập trình bạn đang sử dụng. –

+0

Xin cảm ơn, tôi đã thêm nó – hguser

Trả lời

2

Vâng, tất nhiên. Mẫu mã của bạn không thực sự nhận được thông tin chú thích cho lớp, nhưng đối với các trường, nhưng mã là tương tự. Bạn chỉ cần lấy Class, Method hoặc Field mà bạn quan tâm, sau đó gọi "getAnnotation (AnnotationClass.class)" trên đó.

Điều duy nhất cần lưu ý là định nghĩa chú thích phải sử dụng RetentionPolicy thích hợp để thông tin chú thích được lưu trữ trong mã byte. Một cái gì đó như:

@Target({ElementType.ANNOTATION_TYPE}) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface MyAnnotation { ... } 
+0

Mã của tôi là một Lớp được chú thích và tôi muốn nhận thông tin chú thích của nó trong ứng dụng khách khác. – hguser

+0

Miễn là loại lưu giữ là RUNTIME, các định nghĩa chú thích được lưu trữ cùng với mã Java bytecode và có thể truy cập được ở bất kỳ nơi nào được tải. Điều duy nhất khác cần đưa vào là lớp chú thích (có thể đây là những gì bạn đang tìm kiếm?); trong trường hợp của bạn, nó sẽ là 'Field.class' (đối với chú thích @Field). – StaxMan

+0

Xin chào, cảm ơn, bạn có thể dành chút thời gian để kiểm tra cập nhật của tôi không? :) – hguser

1

Có vẻ như bạn đang sử dụng (Hibernate Search)! Hibernate kiếm có một lớp helper mà có thể lấy các lĩnh vực thông tin

FieldInfos fieldInfos = ReaderUtil.getMergedFieldInfos(indexReader); 

Thật không may FieldsInfos không chứa đủ thông tin (thường là bạn không biết nếu một lĩnh vực được lưu trữ hay không: hoặc có lẽ tôi đã bỏ lỡ một cái gì đó). Đây là triển khai thực hiện của tôi để nhận được tất cả các lĩnh vực lưu trữ:

public class HBSearchHelper { 

/** 
* Get all fields of a entity which are stored into Lucene 
* 
* @param clazz 
* @param prefix 
* @return 
*/ 
public static List<String> getStoredField(Class<?> clazz, String prefix) { 
    List<Field> fields = getAllFields(clazz); 
    ArrayList<String> storedList = new ArrayList<String>(); 
    for (Field fi : fields) { 
     // @Field annotation 
     if (fi.isAnnotationPresent(org.hibernate.search.annotations.Field.class)) { 
      org.hibernate.search.annotations.Field annotation = fi.getAnnotation(org.hibernate.search.annotations.Field.class); 
      String storedName = getStoredFieldName(fi.getName(), annotation); 
      if (storedName != null) { 
       storedList.add(prefix + storedName); 
      } 
     } 
     // @Fields annotation (should contain one or more @Field annotations) 
     if (fi.isAnnotationPresent(org.hibernate.search.annotations.Fields.class)) { 
      org.hibernate.search.annotations.Fields annotation = fi.getAnnotation(org.hibernate.search.annotations.Fields.class); 
      org.hibernate.search.annotations.Field[] subAnnotations = annotation.value(); 
      for (org.hibernate.search.annotations.Field subAnnotation : subAnnotations) { 
       String storedName = getStoredFieldName(fi.getName(), subAnnotation); 
       if (storedName != null) { 
        storedList.add(prefix + storedName); 
       } 
      } 
     } 
     // @IndexedEmbeded annotation 
     if (fi.isAnnotationPresent(org.hibernate.search.annotations.IndexedEmbedded.class)) { 
      org.hibernate.search.annotations.IndexedEmbedded annotation = fi.getAnnotation(org.hibernate.search.annotations.IndexedEmbedded.class); 
      String name = fi.getName(); 
      // If the annotation has declared a prefix then use it instead of the field's name 
      if (annotation.prefix() != null && !annotation.prefix().isEmpty() && !annotation.prefix().equals(".")) { 
       name = annotation.prefix(); 
      } 
      Class<?> embeddedClass = fi.getType(); 
      if (Collection.class.isAssignableFrom(embeddedClass)) { 
       Type embeddedType = fi.getGenericType(); 
       if (embeddedType instanceof ParameterizedType) { 
        Type[] argsType = ((ParameterizedType) embeddedType).getActualTypeArguments(); 
        if (argsType != null && argsType.length > 0) { 
         embeddedClass = (Class<?>) argsType[0]; 
        } 
       } 
      } 
      List<String> nestedFields = getStoredField(embeddedClass, prefix + name + "."); 
      if (nestedFields != null && !nestedFields.isEmpty()) { 
       storedList.addAll(nestedFields); 
      } 
     } 
    } 
    return storedList; 
} 

/** 
* Returns the @Field's name if this @Field is stored otherwise returns null 
* 
* @param propertyName 
*   The name of the bean's property 
* @param field 
*   The declared Hibernate Search annotation 
* @return 
*/ 
private static String getStoredFieldName(String propertyName, org.hibernate.search.annotations.Field annotation) { 
    Store store = annotation.store(); 
    if (store == Store.YES || store == Store.COMPRESS) { 
     String name = propertyName; 
     // If the annotation has declared a name then use it instead of the property's name 
     if (annotation.name() != null && !annotation.name().isEmpty()) { 
      name = annotation.name(); 
     } 
     return name; 
    } 
    return null; 
} 

/** 
* Get all declared fields from the class and its super types 
* 
* @param type 
* @return 
*/ 
private static List<Field> getAllFields(Class<?> type) { 
    List<Field> fields = new ArrayList<Field>(); 
    if (type != null) { 
     fields.addAll(Arrays.asList(type.getDeclaredFields())); 
     fields.addAll(getAllFields(type.getSuperclass())); 
    } 
    return fields; 
} 
} 

Sau đó, nó là khá dễ dàng để lấy lĩnh vực lưu trữ của một thực thể:

List<String> storedFields = HBSearchHelper.getStoredFields(MyEntity.class, ""); 

Nó sẽ làm việc cho:

  • attributs lưu trữ (Stored.YES hoặc Stored.COMPRESS)
  • các thuộc tính đơn giản (có hoặc không có tên được chỉ định)
  • attributs nhúng (có hoặc không có tiền tố)
  • khai đa lĩnh vực (ví dụ @Fields chú thích)

Hy vọng nó có thể giúp ai đó.

Các vấn đề liên quan