質問

実行時にクラスの注釈情報を取得できる方法があるのだろうか? Sepcifilyが注釈を付けたプロパティを取得したいので。

例:

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

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

注釈はHibernate-Searchからのものであり、今私が望んでいるのは、「Testmain」のどのプロパティが得られるかを取得することです 注釈 「フィールド」として(例では、それらは 名前と年齢)、そしてそれは「保存されています(store = store.yes)」(例では、それらは[])実行時。

何か案は?

アップデート:

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=, boost=@org.hibernate.search.annotations.Boost(value=1.0), analyzer=@org.hibernate.search.annotations.Analyzer(impl=void, definition=), bridge=@org.hibernate.search.annotations.FieldBridge(impl=void, params=[]))

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

    }
    return fieldList;
}

}

役に立ちましたか?

解決

はい、もちろん。コードサンプルは実際にはクラスの注釈情報を取得するのではなく、フィールドでは入手しますが、コードは似ています。興味のあるクラス、方法、またはフィールドを取得するだけで、「getannotation(annotationclass.class)」と呼びます。

注目すべき唯一のことは、注釈の定義が適切な保持ポリティを使用して、アノテーション情報がバイトコードに保存されるようにしなければならないということです。何かのようなもの:

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

他のヒント

(Hibernate Search)を使用しているようです! Hibernate Searchには、フィールドの情報を取得できるヘルパークラスがあります

FieldInfos fieldInfos = ReaderUtil.getMergedFieldInfos(indexReader);

残念ながら、FieldSinfosには十分な情報が含まれていません(通常、フィールドが保存されているかどうかはわかりません。すべての保存されたフィールドを取得するための私の実装は次のとおりです。

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

その後、エンティティの保存されたフィールドを取得するのは非常に簡単です。

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

それは次のように機能するはずです:

  • 保存された属性(YEESまたはSTORED.COMPRESS)
  • 単純な属性(指定された名前の有無にかかわらず)
  • 埋め込まれた属性(プレフィックスの有無にかかわらず)
  • マルチフィールド宣言(すなわち@fieldsアノテーション)

それが誰かを助けることができることを願っています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top