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



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

编辑

我上一个问题中的更多信息:无状态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 3.1视图(本地、远程、无接口)
  • EJB 3.1@LocalBean与无注释

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

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

因此,当使用EJB时,不能注入实现,只能注入接口。如果您真的想这样做,我会放弃EJB。

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

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

最新更新