GenericDAO 与 Guice,玩泛型和 ParameterizedType

Posted

技术标签:

【中文标题】GenericDAO 与 Guice,玩泛型和 ParameterizedType【英文标题】:GenericDAO with Guice, playing with Generics and ParameterizedType 【发布时间】:2012-01-24 01:04:43 【问题描述】:

大多数人应该熟悉为 Spring + hibernate 制作通用 DAO。参考来自这里http://www.ibm.com/developerworks/java/library/j-genericdao/index.html,但在Single DAO & generic CRUD methods (JPA/Hibernate + Spring)上有一个改进

这种改进是检测类型,因为它是超类的一部分,而不是使用构造函数来判断它是哪个类

public GenericDaoJpaImpl() 
    ParameterizedType genericSuperclass = (ParameterizedType) getClass()
         .getGenericSuperclass();
    this.entityClass = (Class<T>) genericSuperclass
         .getActualTypeArguments()[0];

但是,这个施法会因 Guice 而失败。要注入,接口和类需要像这样绑定在一个模块中

bind(TestDao.class).to(TestDaoImpl.class);

通过这样做,我们的 GenericDAO 的构造函数将无法工作,原因如下:

getClass().getGenericSuperclass() = java.lang.Class
getClass().getName() = com.gwtplatform.samples.basic.server.dao.TestDaoImpl$$EnhancerByGuice$$5fe0d6fd

与 Spring + Hibernate 返回的相反

getClass().getGenericSuperclass() = sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
getClass().getName() =  com.gwtplatform.samples.basic.server.dao.TestDaoImpl

我现在只是在我的扩展 DAO 中使用超级构造函数,但仍然想获取类型而不是提供它,有什么想法吗?

【问题讨论】:

【参考方案1】:

“guicy”的方式是让 Guice 将 TypeLiteral 注入到您的代码中。

bind(new TypeLiteral<Dao<Foo>>()).to(GenericDAO.class);

然后……。

class GenericDao implements Dao<T>
  @Inject
  GenericDao(TypeLiteral<T> type) 
    this.whatever = type;
  

Guice 知道 T 的类型,很乐意告诉您。 TypeLiteral 具有获取原始基础类型的访问器。

guice 文档中关于这项技术的信息很少,但这篇博文很有帮助:http://blog.publicobject.com/2008/11/guice-punches-erasure-in-face.html

【讨论】:

我将其标记为答案,因为这是获取类型的一种方式,但对我来说,与自己提供类型相比,最后这只是很多代码【参考方案2】:

这些通用技巧让我头疼,如果我在那里,我经常质疑我是否应该这样做,也许有更好的解决方案,但我认为你可以通过在 Guice 中使用 Provider 来做到这一点,所以你是传递实际的类,而不是让 Guice 创建它。所以

public class DAOProvider implements Provider<TestDaoImpl> /*etc*/

bind(TestDao.class).toProvider(new DAOProvider());

【讨论】:

【参考方案3】:

您可以使用以下代码从 Guice 代理获取底层类:

Class<?> clazz = getClass();

if (clazz.getName().contains("EnhancerByGuice")) 
  clazz = clazz.getSuperclass();

【讨论】:

以上是关于GenericDAO 与 Guice,玩泛型和 ParameterizedType的主要内容,如果未能解决你的问题,请参考以下文章

培训作业:泛型和集合

13. 泛型和枚举

使用泛型类简化ibatis系统架构

泛型和List

总结java的泛型和内部类

UML 与泛型和可为空字段的关系