以编程方式从JSF托管的bean中注入EJB bean [英] Inject EJB bean from JSF managed bean programmatically
问题描述
您无法以编程方式注入。但是您可以以编程方式获取它。 也可以通过JNDI使用EJB 。通常,您会发现服务器启动日志中打印的这些JNDI名称/别名。至少JBoss / WildFly这样做。
有不同的JNDI名称别名:
java:全球/ 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的情况下,EJB为EAR或WAR本身)。
JSF管理的bean显然在WAR内。如果您有一个单一的WAR应用程序,那么 java:module / EJB_NAME
必须工作。如果您有一个EAR项目,那么EJB显然在EJB模块中,在这种情况下, java:module
将无法正常工作,您需要 java:app
或 java:global
。
所以,给出如下的EJB,
@Stateless
public class FooService {}
它是通过JNDI命名为foo_war的单一WAR项目在JSF托管的bean中可用如下(通常您在 @PostConstruct
方法中执行此操作):
InitialContext jndi = new InitialContext();
FooService fooService =(FooService)jndi.lookup(java:module / FooService);
//或
FooService fooService =(FooService)jndi.lookup(java:app / foo_war / FooService);
//或
FooService fooService =(FooService)jndi.lookup(java:global / foo_war / FooService);或者在名为foo_ear的名为foo_ejb的EJB模块的EAR项目中,其中包含EJB类(而JSF托管的bean在EAR项目的WAR模块中): InitialContext jndi = new InitialContext();
FooService fooService =(FooService)jndi.lookup(java:app / foo_ejb / FooService);
//或
FooService fooService =(FooService)jndi.lookup(java:global / foo_ear / foo_ejb / FooService);
I have EJB stateless bean.
How can I inject it to JSF managed bean by programmatic instead of @EJB annotation?
解决方案 You can't inject it programmatically. You can however obtain it programmatically. EJBs are also available via JNDI. Usually, you find those JNDI names/aliases printed in server startup log. At least JBoss / WildFly does that.
There are different JNDI name aliases:
java:global/APP_NAME[/MODULE_NAME]/EJB_NAME
java:app/MODULE_NAME/EJB_NAME
java:module/EJB_NAME
Where /APP_NAME
is the name of the WAR or EAR application, and /MODULE_NAME
is the name of the EJB module in case of an EAR application, or the WAR module in case of a single-WAR application (and this will be absent in java:global
as it otherwise repeats /APP_NAME
), and /EJB_NAME
defaults to the class name of the EJB class.
The java:global
is accessible through the entire server. The java:app
is only accessible from inside the same application (WAR or EAR). The java:module
is only accessible from inside the same module (EJB in case of EAR or WAR itself in case of single-WAR).
A JSF managed bean is obviously inside a WAR. If you've a single-WAR application, then java:module/EJB_NAME
must work. If you've however an EAR project, then the EJB is obviously inside the EJB module, in that case the java:module
won't work and you'd need java:app
or java:global
.
So, given an EJB like below,
@Stateless
public class FooService {}
it's in a single-WAR project named "foo_war" via JNDI available in a JSF managed bean as follows (usually you do that in @PostConstruct
method):
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");
or in an EAR project named "foo_ear" with an EJB module named "foo_ejb" with therein the EJB class (while the JSF managed bean is in the WAR module of the EAR project):
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");
这篇关于以编程方式从JSF托管的bean中注入EJB bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!