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的主要内容,如果未能解决你的问题,请参考以下文章