CDI:根据调用者在EJB中注入不同的bean

时间:2014-08-13 12:06:45

标签: jsf ejb cdi

我正在尝试在无状态EJB中注入bean。但是,当从ManagedBean或EJB Timer调用EJB时​​,我希望该bean不同。

这是我在其中注入User bean的EJB:

MyEjb.java

@Stateless
class MyEjb{
    @Inject
    @CurrentContext
    private User user;

    public void foo(){
        System.out.println(user);
    }
}

这是一个使用EJB的EJB Timer:

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

最后,ManagedBean使用MyEjb:

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());
    }
}

当达到超时时,我希望MyEbj的foo方法使用由方法produceCurrentUserInEjbTimer创建的系统User。

当调用ManagedBean的bar方法时,我希望MyEbj的foo方法使用FaceContext的远程User(由方法produceCurrentUserInManagedBean创建)。

1 个答案:

答案 0 :(得分:0)

我宁愿只有一个生产者检查FacesContext.getCurrentInstance()!= null然后调用适当的代码:

public User produceCurrentUser(){
        if(FacesContext.getCurrentInstance() != null){
            return new User(FacesContext.getCurrentInstance().getExternalContext().getRemoteUser());
        }
        else{
             return new User("system");
       }
    }

您也可以直接在定时器或ManagedBean上注入User,然后使用InjectionPoint对象知道您的用户注入了哪个类:

public User produceCurrentUser(InjectionPoint injectionPoint){
      System.out.println(injectionPoint.getBean());
}

您还应该使用@Named和@javax.enterprise.context.SessionScoped,因为您的应用程序上有CDI而不是@ManagedBean。

<强>更新

我不确定是否有直接的方法来获取注入的上下文,它可能会抛出CDI扩展但我从未尝试过。

如何通过编程查找获取上下文实例:

    @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);
    }
}

这是你可以注入你的EJB并将上下文参数传递给foo:

@Named
@SessionScoped
class MyManagedBean {
    @EJB
    private MyEjb myEjb;


    public void bar() {
        myEjb.foo("jsf");
    }
}