[英]CDI: Inject different bean in an EJB depending on the caller
I'm trying to inject a bean in a stateless EJB. 我正在尝试在无状态EJB中注入bean。 But i would like that bean be different when EJB is called from a ManagedBean or from a EJB Timer.
但是我希望当从ManagedBean或EJB Timer调用EJB时,该bean是不同的。
Here is my EJB in which i inject a User bean: 这是我在其中注入User Bean的EJB:
MyEjb.java MyEjb.java
@Stateless
class MyEjb{
@Inject
@CurrentContext
private User user;
public void foo(){
System.out.println(user);
}
}
Here is a EJB Timer that use the EJB: 这是使用EJB的EJB计时器:
TimerTest.java TimerTest.java
@Singleton
@Startup
class TimerTest {
@EJB
private MyEjb myEjb;
@Timeout
public void doIt(Timer timer) {
myEjb.foo();
}
@Produces
@CurrentContext
public User produceCurrentUserInEjbTimer(){
return new User("system");
}
}
Finally, the ManagedBean using MyEjb : 最后,使用MyEjb的ManagedBean:
MyManagedBean.java MyManagedBean.java
@ManagedBean
@SessionScoped
class MyManagedBean {
@EJB
private MyEjb myEjb;
public void bar() {
myEjb.foo();
}
@Produces
@CurrentContext
@RequestScoped
public User produceCurrentUserInManagedBean(){
return new User(FacesContext.getCurrentInstance().getExternalContext().getRemoteUser());
}
}
When the timeout is reach, i would like that foo method of MyEbj use the system User created by the method produceCurrentUserInEjbTimer. 当达到超时时,我希望MyEbj的foo方法使用由generateCurrentUserInEjbTimer方法创建的系统User。
And when the bar method of the ManagedBean is invoked, i would like that foo method of MyEbj use the remote User of the FaceContext (created by the method produceCurrentUserInManagedBean). 当调用ManagedBean的bar方法时,我希望MyEbj的foo方法使用FaceContext的远程用户(由produceCurrentUserInManagedBean方法创建)。
I would rather have only one producer that checks if FacesContext.getCurrentInstance() != null then call the apropriate code: 我宁愿只有一个生产者来检查FacesContext.getCurrentInstance()!= null,然后调用适当的代码:
public User produceCurrentUser(){
if(FacesContext.getCurrentInstance() != null){
return new User(FacesContext.getCurrentInstance().getExternalContext().getRemoteUser());
}
else{
return new User("system");
}
}
You can also inject you User directly on the timer or the ManagedBean and then use InjectionPoint object to know to which class your User is injected: 您还可以直接在计时器或ManagedBean上注入User,然后使用InjectionPoint对象来知道将User注入到哪个类:
public User produceCurrentUser(InjectionPoint injectionPoint){
System.out.println(injectionPoint.getBean());
}
You should also use @Named and @javax.enterprise.context.SessionScoped as you have CDI on your application instead of @ManagedBean. 您还应该使用@Named和@ javax.enterprise.context.SessionScoped,因为应用程序上具有CDI而不是@ManagedBean。
UPDATE 更新
I'm not sure that there is a direct method to get the context of the injection, it wil be possible throw CDI extension but I've never try it. 我不确定是否有直接方法来获取注入的上下文,是否有可能抛出CDI扩展,但我从未尝试过。
What about obtaining a contextual instance by programmatic lookup: 通过编程查找获取上下文实例呢:
@Stateless
class MyEjb{
@Inject @Any Instance<User> userSource;
public void foo(String context) // you should define contexts your self as jms, jsf ...
{
// Every expected context will have a qualifier
Annotation qualifier = context.equals("jsf") ?
new JSFQualifier() : new JMSQualifier();
User p = userSource.select(qualifier).get();
System.out.println(user);
}
}
This was you can inject your EJB and pass the context param to foo: 这是您可以注入EJB并将上下文参数传递给foo:
@Named
@SessionScoped
class MyManagedBean {
@EJB
private MyEjb myEjb;
public void bar() {
myEjb.foo("jsf");
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.