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

pha*_*cit 6 jsf ejb code-injection managed-bean

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

Bal*_*usC 8

您无法以编程方式注入它.但是,您可以通过编程方式获取它.EJB也可以通过JNDI获得.通常,您会在服务器启动日志中找到打印的JNDI名称/别名.至少JBoss/WildFly会这样做.

有不同的JNDI名称别名:

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

/APP_NAMEWAR或EAR应用程序的名称在哪里,在EAR应用程序的/MODULE_NAME情况下是EJB模块的名称,在单WAR应用程序的情况下是WAR模块的名称(这将在java:global其他情况下重复出现/APP_NAME) ,/EJB_NAME默认为EJB类的类名.

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

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

所以,给定如下的EJB,

@Stateless
public class FooService {}
Run Code Online (Sandbox Code Playgroud)

它位于一个名为"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");
Run Code Online (Sandbox Code Playgroud)

或者在一个名为"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");
Run Code Online (Sandbox Code Playgroud)