我的一个类具有使用@EJB注释声明的属性。
有两个bean是合格的,所以我得到一个不错的org.jboss.weld.exceptions.DeploymentException: WELD-001409 Ambiguous dependencies
。
我知道可以使用限定词解决此问题。但这会让我选择一个EJB实现而不是另一个。但是我真的不在乎使用哪个。有没有简单的方法告诉CDI“选择两个合格的实现中的任何一个,我不在乎,而且都很好”?
最佳答案
...告诉CDI的简单方法“选择两个合格的实现中的任何一个,我不在乎,而且都很好”
不,那里没有。这将与CDI试图实现的目标背道而驰。这是为什么的一个高峰...
一种情况是您的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。