GenericDAO с Guice, игра с Generics и ParameterizedType - PullRequest
1 голос
/ 20 декабря 2011

большинство людей должны быть знакомы с созданием универсального DAO для Spring + hibernate.Отсюда ссылка 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];
}

ОДНАКО, приведение завершится неудачно с 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, но все же хотел бы получить тип вместо предоставления любого, любогоидеи?

Ответы [ 3 ]

5 голосов
/ 20 декабря 2011

Способ "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 есть средства доступа для получения необработанного базового типа.

Документы-подсказки имеют очень мало информации об этой технике, но этот пост полезен: http://blog.publicobject.com/2008/11/guice-punches-erasure-in-face.html

1 голос
/ 20 декабря 2011

Подобные общие трюки делают мою голову больной, и если я там, я часто спрашиваю, должен ли я быть, возможно, есть лучшее решение, но я думаю, что вы можете сделать это, используя провайдера в Guice, так что вы передавая фактический класс, вместо того, чтобы позволить Guice создать его. Так

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

bind(TestDao.class).toProvider(new DAOProvider());
0 голосов
/ 05 сентября 2013

Вы можете получить базовый класс от прокси Guice с этим кодом:

Class<?> clazz = getClass();

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