我有EJB无状态bean 如何通过programmatic而不是@EJB注释将其注入JSF托管bean?
答案 0 :(得分:7)
您无法以编程方式注入它。但是,您可以通过编程方式获取它。 EJBs are also available via 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
只能从同一模块内部访问(如果是单一WAR,则在EAR或WAR本身的情况下为EJB)。
JSF托管bean显然在WAR中。如果您有单个WAR应用程序,则java:module/EJB_NAME
必须正常工作。如果你是一个EAR项目,那么EJB显然在EJB模块中,在这种情况下,java:module
将不起作用,你需要java:app
或java: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类(而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");