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

Is it possible to inject EJB implementation and not its interface using CDI?

我的配置是: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
}

编辑

我上一个问题的更多信息:

看起来你在之前的问题中得到了一个不清楚的答案,实际上所有这个问题都是对那个问题的跟进。

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

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

是的,你可以,但是当 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 默认定义一个无接口视图:

@Stateless
class Bean {
...
}  

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

另请参阅:

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

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