如何在无状态EJB bean中调用托管bean?

时间:2013-09-26 10:42:45

标签: jsf jsf-2 ejb ejb-3.1 managed-bean

我想知道,是否有任何选项可以在EJB bean中调用托管bean。想象一下,我们有代码:

@ManagedBean
@SessionScoped
public class MyManagedBean implements Serializable {
  public String getUrl() {
      return "http://www.google.com";
  }
}

@Stateless
public class MyEJB {

  @ManagedProperty(value = "#{myManagedBean}")
  MyManagedBean myManagedBean;

  public void setMyManagedBean(MyManagedBean myManagedBean) {
      this.myManagedBean = myManagedBean;
  }

  public void call() {
      // NullPointerException here
      System.out.println(myManagedBean.getUrl());         
  }
}

我也试过这个:

@Stateless
public class MyEJB {
  @EJB
  MyManagedBean myManagedBean;
  ...
}

...但它会返回不同的MyManagedBean实例。

1 个答案:

答案 0 :(得分:3)

这是不对的。使用CDI托管bean而不是JSF托管bean,这是可能的,但它不是正确的,糟糕的设计。业务服务根本不应该了解前端。它使得业务服务在其他前端无法使用,而不是JSF。

你应该反过来做。您应该在托管bean中注入EJB,而不是相反。 EJB应该完全无状态。您应该直接向EJB传递它需要的信息作为方法参数(并且从不之后将其作为EJB的实例变量分配)。

E.g。

@ManagedBean
@SessionScoped // <-- Did you read https://stackoverflow.com/q/7031885?
public class MyManagedBean implements Serializable {

    private String url = "http://www.google.com";

    @EJB
    private MyEJB myEJB;

    public void submit() {
        myEJB.call(url);
    }

    public String getUrl() {
        return url;
    }

}

@Stateless
public class MyEJB {

    public void call(String url) {
        // No NullPointerException here.
        System.out.println(url);
    }

}

另见: