我想知道是否有任何方法可以在运行时获取类的注释信息?因为我想要获得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;
}
}
答案 0 :(得分:2)
是的,当然。您的代码示例实际上并没有获取类的注释信息,但是对于字段,但代码类似。你只需要获得你感兴趣的Class,Method或Field,然后在其上调用“getAnnotation(AnnotationClass.class)”。
唯一需要注意的是注释定义必须使用适当的RetentionPolicy,以便注释信息存储在字节代码中。类似的东西:
@Target({ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation { ... }
答案 1 :(得分:1)
好像你正在使用(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, "");
它适用于:
希望它可以帮助别人。