是否可以使用CDI注入EJB实现而不是其接口?

时间:2015-12-22 08:23:55

标签: java dependency-injection ejb cdi weld

我的配置是:Wildfly 8.2.0,Weld

是否可以在bean中注入,而不是在CDI的接口中注入?

@Stateless
class Bean implements IBean {
...
}    

interface IBean {
...
}

@SessionScoped
class Scoped {
   @Inject
   Bean bean; //Fail

   @Inject
   IBean iBean; //OK
}

编辑

我之前提问的更多信息: Stateless EJB implements interface injection failed

3 个答案:

答案 0 :(得分:20)

是的,您可以,但是当EJB注入业务视图时,您公开的唯一业务视图是@Local视图,这是您实现接口时的默认视图(在您的案例中IBean是本地视图业务接口)。因此,如果要自己注入bean,则需要告诉容器您正在使用无接口视图。

在您的示例中,如果您仍想实现接口并注入Bean,则应使用@LocalBean注释,这意味着bean公开了无接口视图:

@Stateless
@LocalBean // <-- no-interface view
class Bean implements IBean {
...
}  

interface IBean {
....
}

@SessionScoped
class Scoped {
   @Inject
   Bean bean; //Should be OK
}

或者,如果您不想实现任何接口,那么bean默认定义一个No-Interface视图:

@Stateless
class Bean {
...
}  

@SessionScoped
class Scoped {
   @Inject
   Bean bean; //OK
}

另见:

答案 1 :(得分:2)

在您之前的问题中,您似乎得到了一个不明确的答案,而且所有这些问题都是对该问题的跟进。

一般来说,CDI允许您为CDI托管bean注入接口和impl。这不是EJB的情况。当EJB实现接口时,它将成为其业务接口。只有在那里声明的方法才有效。实际上,您的Bean类仅定义这些方法的工作方式,并且实际上并不作为运行时中的bean存在。

所以不,在使用EJB时​​,您不能注入实现,只能注入接口。如果你真的想这样做,我会离开EJB。

答案 2 :(得分:0)

您可能不愿意使用该接口来注入EJB的可能原因之一可能是您可能有许多实现此接口的EJB,并且您的EJB容器可能抱怨说它无法解决哪个特定对象的歧义EJB必须在给定的上下文中注入。在这种情况下,您可以使用javax.inject.Named注释轻松地指定实现公共接口的具体EJB类的名称,如下所示:

@SessionScoped
class Scoped {
   @Named("Bean")
   IBean iBean;
}