使用Guice的GenericDAO,使用Generics和ParameterizedType

jav*_*ber 1 java generics hibernate guice

大多数人应该熟悉为Spring + hibernate制作Generic DAO.参考资料来自http://www.ibm.com/developerworks/java/library/j-genericdao/index.html,单DAO和通用CRUD方法(JPA/Hibernate + Spring)有所改进

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

public GenericDaoJpaImpl() {
    ParameterizedType genericSuperclass = (ParameterizedType) getClass()
         .getGenericSuperclass();
    this.entityClass = (Class<T>) genericSuperclass
         .getActualTypeArguments()[0];
}
Run Code Online (Sandbox Code Playgroud)

但是,这个演员会因Guice而失败.要注入,接口和类需要绑定在这样的模块中

bind(TestDao.class).to(TestDaoImpl.class);
Run Code Online (Sandbox Code Playgroud)

通过这样做,我们的GenericDAO的构造函数将无法工作,因为以下内容:

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

与Spring + Hibernate返回的内容相反

getClass().getGenericSuperclass() = sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
getClass().getName() =  com.gwtplatform.samples.basic.server.dao.TestDaoImpl
Run Code Online (Sandbox Code Playgroud)

我现在只是在我的扩展DAO中使用超级构造函数,但是仍然希望获得该类型而不是提供它,任何想法?

Dar*_*roy 5

"guicy"方式是让Guice在你的代码中注入一个TypeLiteral.

bind(new TypeLiteral<Dao<Foo>>(){}).to(GenericDAO.class);
Run Code Online (Sandbox Code Playgroud)

然后….

class GenericDao implements Dao<T>
  @Inject
  GenericDao(TypeLiteral<T> type) {
    this.whatever = type;
  }
}
Run Code Online (Sandbox Code Playgroud)

Guice知道T的类型,很高兴告诉你.TypeLiteral具有访问器以获取原始基础类型.

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