是否可以使用 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
}
另请参阅:
- What is local/remote and no-interface view in EJB?
- Defining EJB 3.1 Views (Local, Remote, No-Interface)
- EJB 3.1 @LocalBean vs no annotation
您可能不愿意使用该接口来注入 EJB 的一个可能原因可能是您可能有许多实现此接口的 EJB,并且您的 EJB 容器可能抱怨它无法解决在给定的上下文中必须注入哪个特定的 EJB。如果是这种情况,您可以使用 javax.inject.Named
注释轻松指定实现公共接口的具体 EJB class 的名称,如下所示:
@SessionScoped
class Scoped {
@Named("Bean")
IBean iBean;
}
我的配置是: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
}
另请参阅:
- What is local/remote and no-interface view in EJB?
- Defining EJB 3.1 Views (Local, Remote, No-Interface)
- EJB 3.1 @LocalBean vs no annotation
您可能不愿意使用该接口来注入 EJB 的一个可能原因可能是您可能有许多实现此接口的 EJB,并且您的 EJB 容器可能抱怨它无法解决在给定的上下文中必须注入哪个特定的 EJB。如果是这种情况,您可以使用 javax.inject.Named
注释轻松指定实现公共接口的具体 EJB class 的名称,如下所示:
@SessionScoped
class Scoped {
@Named("Bean")
IBean iBean;
}