使用 CDI/Weld 注入通用 Bean
我刚刚从我美好的 JavaSE/Guice 小世界回来,目前正在探索“容器承载”的路径 - EE6。在使用 Glassfish3.1 遇到一些问题后,我刚刚切换到 JBoss,现在面临着一个不应该出现的问题。
作为基础设施辅助类,我尝试为任何类型的实体创建通用存储库/DAO。以一种非常简单的方式,这可能看起来像这样。
public class Repository<E, K extends Serializable & Comparable<K>> {
private final Instance<EntityManager> entityManagerInstance;
protected final Class<E> getDomainObjectClass() {
return domainObjectClass;
}
private final Class<E> domainObjectClass;
protected final EntityManager getEntityManager() {
return entityManagerInstance.get();
}
@Inject
public Repository(Instance<EntityManager> entityManageryProvider, Provider<E> domainObjectProvider) {
//This is a dirty hack, sadly :(
domainObjectClass = (Class<E>)domainObjectProvider.get().getClass();
this.entityManagerInstance = entityManageryProvider;
}
public final void persist(E domainObject) {
final EntityManager em = getEntityManager();
em.persist(domainObject);
}
public final Collection<E> getAllEntities() {
final EntityManager em = getEntityManager();
final CriteriaBuilder cb = em.getCriteriaBuilder();
final CriteriaQuery<E> query = cb.createQuery(getDomainObjectClass());
final List<E> result = em.createQuery(query).getResultList();
return Collections.unmodifiableList(result);
}
public final E find(K id) {
Preconditions.checkNotNull(id);
final EntityManager em = getEntityManager();
return em.find(getDomainObjectClass(), id);
}
// [...]
}
现在可能有一个 bean 不需要依赖于实体的查询功能,而只需要某种实体类型的存储库,例如(可能是一个测试用例):
public class DomainObjectARepositoryTest{
@Inject
Repository<DomainObjectA, PersistableUUID> domainObjectARepository;
@Test
public void testMitarbeitererstellung() {
for (DomainObjectA a : domainObjectARepository.getAllEntities()) {
// do cool stuff
}
}
}
不幸的是,Weld 似乎不喜欢这种通用注入。在部署时,我收到以下错误:
state=Create: org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [Repository<DomainObjectA , PersistableUUID>] with qualifiers [@Default] at injection point [[field] @Inject sompackage.DomainObjectARepositoryTest.domainObjectARepository]
我是否遗漏了某些内容,或者他们只是忘记实现通用注入?据我了解通用的东西,无论如何,它在编译后都会被删除 - 即使到目前为止,这在 guice3 中工作得很好。
亲切的问候,
avi
编辑:发现 garvin king 的评论,该行为在规范中,但未在焊接中实现, (声明于2009年6月)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是一个很长的评论,而不是对你的问题的完整答案,但可能会为你指明正确的方向:
我正在关注 seam-dev & 中的讨论。焊接开发已经有一段时间了,并且不记得曾经出现过类似的事情。所以我的猜测是,自从加文发表评论以来,它就没有被提上议程。
你可以相对容易地验证这个假设:
(a) 获取对 BeanManager 的引用并查询它以获取相关的 bean 类型(或者只是将
Object
放在保存端)您必须在DomainObjectARepositoryTest
中删除@Inject
才能启动应用程序。(b) 注册扩展并监听 ProcessBean 以了解部署期间发生的情况。这将是我建议的方法,您会找到更多信息此处。
有了这个结果,您绝对应该能够判断是否有任何 bean 类型
Repository>
徘徊:-)如果您能在此处报告结果并考虑在负面情况下提交 Jira 问题,那就太好了。
That's rather a long comment than a complete answer to your question, but might point you in the right direction:
I'm following the discussions in seam-dev & weld-dev since quite some time, and do not remember that anything like this ever popped up. So my guess would be that it hasn't been on the agenda ever since Gavin commented about it.
What you can do relatively easy to verify this assumption:
(a) Obtain a reference to the BeanManager and query it for the relevant bean type (or just for
Object
to be on the save side), of course you will have to remove@Inject
inDomainObjectARepositoryTest
in order to get the application started.(b) Register an extension and listen to
ProcessBean
to what comes up during the deployment. That would be my suggested way to go, you'll find more information here.With that outcome you should definitely be able to tell if there are any bean types
Repository<E, K extends Serializable & Comparable<K>>
hanging around :-)Would be cool if you'd report back here with the results and also considered filing a Jira issue in the negative case.