2016-01-06 67 views
0

我正在研究一些使用hibernate实现的web服务。问题是我需要访问实体表的名称(比如@Table(“Table_A”))。 代码生成了,所以我不能改变实体类自己给我我需要的东西。这是缓存反射数据的正确方法吗?

这是我到目前为止做:

public static 
<T extends Entity<K>, K extends Serializable> 
String getTableName(Class<T> objClass) { 
    Table table = objClass.getAnnotation(Table.class); 
    return (table != null)? table.name() : null; 
} 

然而,经过一番研究,我发现,反思是不是最好的性能,明智的,因为这种方法将被调用了很多我在寻找另一种方式去实现它。

我试图按照这里给出的建议: Performance of calling Method/Field.getAnnotation(Class) several times vs. Pre-caching this data in a Map

这是我想出了:

public final class EntityUtils { 
    private static HashMap<String, String> entityCache; 

    private EntityUtils() { 
     entityCache = new HashMap<String, String>(); 
    } 

    public static 
    <T extends Entity<K>, K extends Serializable> 
    String getTableName_New(Class<T> objClass) { 
     String tableName = entityCache.get(objClass.getCanonicalName()); 

     if (tableName == null) { 
      Table table = objClass.getAnnotation(Table.class); 

      if (table != null) { 
       tableName = table.name(); 
       entityCache.put(objClass.getCanonicalName(), tableName); 
      } 
     } 

     return tableName; 
    } 
} 

但是,我不知道这件事。在静态地图中缓存反射数据是一个好主意吗?有没有其他方法可以实现这一目标?

+1

注如果没有指定'@ Table'注释,那么Sean的答案中的key.getSimpleName()就是缺省表名。添加这个功能还有一个好处,那就是确保在你的地图上为每个请求的类添加一个etry。在您的实际代码中,缺少一个'@ Table'注释将始终执行反射查找以仅查找null。 – A4L

回答

2

理想情况下,我会使用一个带有弱键的Guava缓存,这样您在使用某些高级ClassLoader魔法时就不会保留对类对象的任何引用。

LoadingCache<Class<?>, String> tableNames = CacheBuilder.newBuilder() 
     .weakKeys() 
     .build(
      new CacheLoader<Class<?>, String>() { 
      public String load(Class<?> key) { 
       Table table = objClass.getAnnotation(Table.class); 
       return table == null ? key.getSimpleName() : table.name(); 
      } 
      }); 

用法:

String tablename = tableNames.get(yourClass); 

参见:Caches Explained


在另一方面:注释是由JDK缓存也,所以你以前的做法可能是罚款

相关问题