以编程方式从 JSF 托管 bean 注入 EJB bean

Inject EJB bean from JSF managed bean programmatically

我有 EJB 无状态 bean。
我如何通过编程而不是 @EJB 注释将它注入 JSF 托管 bean?

您不能以编程方式注入它。但是,您可以通过编程方式获取它。 EJBs are also available via JNDI。通常,您会在服务器启动日志中找到那些打印的 JNDI names/aliases。至少 JBoss / WildFly 做到了。

有不同的 JNDI 名称别名:

java:global/APP_NAME[/MODULE_NAME]/EJB_NAME
java:app/MODULE_NAME/EJB_NAME
java:module/EJB_NAME

其中 /APP_NAME 是 WAR 或 EAR 应用程序的名称,/MODULE_NAME 是 EJB 模块的名称(如果是 EAR 应用程序),或者 WAR 模块在单个 WAR 应用程序的情况下(这将在 java:global 中不存在,否则它会重复 /APP_NAME),并且 /EJB_NAME 默认为 class EJB 的名称 class.

java:global 可通过整个服务器访问。 java:app 只能从同一应用程序(WAR 或 EAR)内部访问。 java:module 只能从同一模块内部访问(在 EAR 的情况下是 EJB,在单个 WAR 的情况下是 WAR 本身)。

一个 JSF 托管 bean 显然在 WAR 中。如果你有一个单一的 WAR 应用程序,那么 java:module/EJB_NAME 必须工作。但是,如果您有一个 EAR 项目,那么 EJB 显然在 EJB 模块中,在这种情况下 java:module 将不起作用,您需要 java:appjava:global

因此,给定如下所示的 EJB,

@Stateless
public class FooService {}

它位于一个名为 "foo_war" 的单个 WAR 项目中,通过 JNDI 在 JSF 托管 bean 中可用,如下所示(通常您在 @PostConstruct 方法中这样做):

InitialContext jndi = new InitialContext();

FooService fooService = (FooService) jndi.lookup("java:module/FooService");
// Or
FooService fooService = (FooService) jndi.lookup("java:app/foo_war/FooService");
// Or
FooService fooService = (FooService) jndi.lookup("java:global/foo_war/FooService");

或在名为 "foo_ear" 的 EAR 项目中,其中包含名为 "foo_ejb" 的 EJB 模块,其中包含 EJB class(而 JSF 托管 bean 位于 WAR 模块中EAR 项目):

InitialContext jndi = new InitialContext();

FooService fooService = (FooService) jndi.lookup("java:app/foo_ejb/FooService");
// Or
FooService fooService = (FooService) jndi.lookup("java:global/foo_ear/foo_ejb/FooService");