设置
假设您有两个bean归档模块A和B,其中A依赖于B(我们不能修改B)。在B中,假设有一个类,其中注入了EntityManager,如下所示:
@Dependent
class SomeClassImpl implements SomeClass {
private EntityManager em;
public SomeClassImpl() {}
@Inject
public SomeClassImpl(EntityManager em) {
this.em = em;
}
...
}
- 请注意,
SomeClass
接口从不直接注入A。也就是说,SomeClass
是SomeRepository
的依赖项,而SomeRepository
又是SomeUseCase
的依赖项,这就是注入A的内容。
因为实体管理器不是一个cdibean,所以我们可以在A中定义它的生产者在WAR归档中部署时,这将按照预期工作。
问题
现在,考虑以下情况:你有三个bean归档模块X、Y和Z,其中X和Y都依赖于Z,如上所定义。因为X和Y为EntityManager定义了一个生产者(X和Y不同),并且这些生产者对所有模块都是可见的,所以我们必须向X和Y的生产者添加限定符以避免不满足的依赖异常。
现在,问题是我们如何处理Z中的模糊性?
如果生产者只对定义的模块可见,那么这将减少第一个场景。但是因为它们不是,所以我们将得到org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type EntityManager with qualifiers
注意:虽然这可以通过自定义作用域来解决,但如果可能的话,我希望现在避免构建一个。
如果是你,你会如何着手解决这个问题?
1条答案
按热度按时间lkaoscv71#
由于您有两个相同类型的bean(两个EntityManagers),因此必须使用限定符来区分它们。但是如何定义
EntityManager
的2个合格示例中的哪一个被注入到SomeClassImpl
中呢?幸运的是,
SomeClassImpl
使用构造函数注入,因此您可以自己构造它。我建议使用两个生产者方法(可以在同一个bean中),每个方法都提供一个手工构造的、限定的SomeClassImpl
示例;假设@Q1
和@Q2
是限定符且2个不同的EntityManager
也由@Q1
,@Q2
限定:CDI仍然会找到一个不合格的
SomeClassImpl
示例,并且可能会抱怨不明确的依赖关系。如果是这样,我将尝试使用beans.xml
(<scan><exclude>
元素)的排除机制从bean发现中排除不合格的SomeClassImpl
。