我的一个类有一个使用@EJB注释声明的属性。
两个豆子符合条件,所以我得到了一个很好的org.jboss.weld.exceptions.DeploymentException: WELD-001409 Ambiguous dependencies
。
我知道这可以通过限定符来解决。但这会让我选择一个EJB实现而不是另一个。但我真的不在乎使用哪一个。有没有一种简单的方法告诉CDI"选择两个符合条件的实施中的任何一个,我都不在乎,两者都很好" ?
答案 0 :(得分:2)
...告诉CDI的一个简单方法“选择两个符合条件的实施中的任何一个,我不在乎,两者都很好”
没有。这将违背CDI试图实现的目标。这是一个高峰,为什么......
有一种情况可能是您的bean是例如会话bean。在这种情况下,为注入点设置两个拟合bean并不意味着它们在您请求它们的给定时刻内甚至存在。毋庸置疑,他们可能无法携带您期望他们拥有的数据/状态。
另一个原因是CDI有一个底层代理系统 - 每个@Inject
ed bean实际上是该bean的代理对象。为了避免在运行时出现奇怪的NPE和异常,CDI需要在启动时知道注入点的一个拟合bean是什么。
另一点可能是您可以注入的bean的不同生命周期管理。这样会产生更奇怪的运行时错误。
最后但并非最不重要的是,想象您的应用越来越大。有人添加了您正在注入的类型的第三个实现,并且对于您想要实现的目标,不精细。那会发生什么?
那就是我的头脑。至于要走的路,您可以使用Instance<MyBean>
或通过BeanManager
解决问题。以下是Instance
的摘录,这可能是更好的方式。
@Inject
private Instance<Foo> foo;
public void doStuff() {
foo.isAmbiguous(); //you can check if there are more beans eligible for injection here
foo.isResolvable(); //yet another useful check you might want
// there are multiple selects you can use - based on type, annotation or both
//select based on annotation (parameter is annotation INSTANCE), with this you require a Foo type with @Default qualifier
foo.select(Default.Literal.INSTANCE).get();
//select based on requested type, here you are asking for a Foo bean which also has a type MyType (implements interface or extends class with that type for instance)
foo.select(MyType.class).get();
// combined - type and annotation
foo.select(MyType.class, Default.Literal.INSTANCE).get();
}
注意:使用Instance<X>
时,方法get()
是实际解决方案的内容,并为您提供结果bean。
答案 1 :(得分:0)
您可以使用Instance<X>
执行此操作:
@Inject
private Instance<MyEjb> myEjbs;
public void myMethod() {
MyEjb myEjb = myEjbs.iterator().next();
myEjb.doSomething();
}