从JSF管理的bean中以编程方式注入EJB bean

8

我有一个EJB无状态bean。
如何通过编程方式将其注入到JSF托管的bean中,而不是使用@EJB注释?

1个回答

10

你无法通过编程方式注入它。但是你可以通过编程方式获取它。EJBs 也可通过 JNDI 获取。通常情况下,这些 JNDI 名称/别名会在服务器启动日志中打印出来。至少 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 是 EAR 应用程序的 EJB 模块的名称,在单个 WAR 应用程序的情况下为 WAR 模块的名称(在 java:global 中将不存在,因为它会重复 /APP_NAME),并且 /EJB_NAME 默认为 EJB 类的类名。

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 {}

您可以通过JNDI在JSF托管的Bean中以以下方式(通常在@PostConstruct方法中执行)访问名为“foo_war”的单一WAR项目:

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 类(而 JSF 托管的 bean 在 EAR 项目的 WAR 模块中):

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");

在运行时获取应用程序和/或模块名称,请参阅如何为JNDI查找配置模块和应用程序名称 - ltlBeBoy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接